# importing required libraries
from PyQt5 import QtCore, QtGui, QtWidgets
# from PyQt5 import QtWidgets
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtPrintSupport import *
import os
import random
import sys
import subprocess
import sqlite3
import requests
import datetime
import time
import io
import webbrowser

build_version = "Version V:1.0.3.5-featured (Official build) (64-bit)"

# main window
class BrowserWindow(QMainWindow):

    # constructor
    def __init__(self, *args, **kwargs):
        super(BrowserWindow, self).__init__()
        self.resize(1800, 1000)
        # creating a tab widget
        self.tabs = QTabWidget()

        # making document mode true
        self.tabs.setDocumentMode(True)

        # adding action when double clicked
        self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick)

        # adding action when tab is changed
        self.tabs.currentChanged.connect(self.current_tab_changed)

        # making tabs closeable
        self.tabs.setTabsClosable(True)

        # adding action when tab close is requested
        self.tabs.tabCloseRequested.connect(self.close_current_tab)

        # making tabs as central widget
        self.setCentralWidget(self.tabs)

        # loding stylesheet
        f = open("static/style.css", "r")
        self.setStyleSheet(f.read())

        # connecting database
        self.conn = sqlite3.connect('static/devsat.db')
        # fetching data from database
        db_res = self.conn.execute("select * from devsat where id=1")
        result = db_res.fetchall()
        self.db_result = result[0]

        self.initui()

    def initui(self):

        self.tabs.setTabShape(QtWidgets.QTabWidget.Triangular)

        # creating a status bar

        self.status = QStatusBar()
        self.status.setFixedHeight(0)
        # self.topbar
        # setting status bar to the main window
        self.setStatusBar(self.status)

        # creating a tool bar for navigation
        navtb = QToolBar("Navigation")

        # adding tool bar tot he main window
        self.addToolBar(navtb)

        # creating back action
        back_btn = QAction(self)
        back_btn.setIcon(QIcon("static/back.png"))

        # setting status tip
        back_btn.setStatusTip("Back to previous page")

        # adding action to back button
        # making current tab to go back
        back_btn.triggered.connect(self.tabback)

        # adding this to the navigation tool bar
        navtb.addAction(back_btn)

        # similarly adding next button
        next_btn = QAction(self)
        next_btn.setIcon(QIcon("static/front.png"))
        next_btn.setStatusTip("Forward to next page")
        next_btn.triggered.connect(self.tabforward)
        navtb.addAction(next_btn)

        # similarly adding reload button
        reload_btn = QAction(self)
        reload_btn.setIcon(QIcon("static/reload.png"))
        reload_btn.setStatusTip("Reload page")
        reload_btn.triggered.connect(self.tabReload)
        navtb.addAction(reload_btn)

        # creating home action
        home_btn = QAction(self)
        home_btn.setIcon(QIcon("static/home.png"))
        home_btn.setStatusTip("Go home")

        # adding action to home button
        home_btn.triggered.connect(self.navigate_home)
        navtb.addAction(home_btn)

        # adding a separator
        navtb.addSeparator()

        # creating a line edit widget for URL
        self.urlbar = QLineEdit()
        self.urlbar.setStyleSheet("border:1px solid white; border-radius:20px;")

        # adding action to line edit when return key is pressed
        self.urlbar.returnPressed.connect(self.navigate_to_url)

        # adding line edit to tool bar
        navtb.addWidget(self.urlbar)

        # added download menu
        downMenu = QMenu()
        downMenu.setStyleSheet(
            "background-color:rgb(80, 80, 80); width:400px; padding:10px; color:white; font-size:16px;")

        self.down = QAction(self)

        self.down.setText("no downloads")
        self.down.setStatusTip("Save current page as html")
        self.down.triggered.connect(lambda: self.settingui(5))
        downMenu.addAction(self.down)

        self.opend = QAction(self)
        self.opend.setText("")
        self.openpath = ""

        self.opend.setStatusTip("Save current page as html")
        self.opend.triggered.connect(lambda: self.openloc())
        downMenu.addAction(self.opend)

        save_btn = QToolButton()
        # tb_set.clicked.connect(self.on_click_set_value)
        save_btn.setIcon(QIcon("static/save.png"))
        # adding menu to nevbar
        save_btn.setMenu(downMenu)
        save_btn.setPopupMode(QToolButton.InstantPopup)
        navtb.addWidget(save_btn)

        # adding bookmark btn
        mark_btn = QAction(self)
        mark_btn.setIcon(QIcon("static/bookmark.png"))
        mark_btn.setStatusTip("bookmark")
        mark_btn.triggered.connect(self.loadstop)
        navtb.addAction(mark_btn)

        # similarly adding stop action
        stop_btn = QAction(self)
        stop_btn.setIcon(QIcon("static/close.png"))
        stop_btn.setStatusTip("Stop loading current page")
        stop_btn.triggered.connect(self.loadstop)
        navtb.addAction(stop_btn)

        navtb.addSeparator()

        # adding login action
        login_btn = QAction(self)
        # login_btn.triggered.connect(lambda: self.tabs.currentWidget().stop())
        if self.db_result[2] == "":
            login_btn.setIcon(QIcon("static/user-red.png"))
            login_btn.setText("log-in")
            login_btn.setStatusTip("log-in required")
        else:
            login_btn.setStatusTip("logged-in")
            login_btn.setIcon(QIcon("static/user-green.png"))
        navtb.addAction(login_btn)

        navtb.addSeparator()

        # creating menu
        SettingMenu = QMenu()
        SettingMenu.setStyleSheet(
            "background-color:rgb(41, 40, 40); width:200px; padding:20px; color:white; font-size:20px;")

        # similarly adding save page action
        save_btn = QAction(self)
        save_btn.setIcon(QIcon("static/save.png"))
        save_btn.setText("Save page")
        save_btn.setStatusTip("Save current page as html")
        save_btn.triggered.connect(self.save_file)
        SettingMenu.addAction(save_btn)

        # adding print button
        print_btn = QAction(self)
        print_btn.setIcon(QIcon("static/print.png"))
        print_btn.setText("print")
        print_btn.setStatusTip("personalize")
        print_btn.triggered.connect(lambda: self.print())
        SettingMenu.addAction(print_btn)

        SettingMenu.addSeparator()
        # adding settings button
        settings_btn = QAction(self)
        settings_btn.setIcon(QIcon("static/setting.png"))
        settings_btn.setText("settings")
        settings_btn.setStatusTip("personalize")
        settings_btn.triggered.connect(lambda: self.settingui())
        SettingMenu.addAction(settings_btn)

        tool_btn = QToolButton()
        # tb_set.clicked.connect(self.on_click_set_value)
        tool_btn.setIcon(QIcon("static/dots.png"))

        tool_btn.setMenu(SettingMenu)
        tool_btn.setPopupMode(QToolButton.InstantPopup)
        navtb.addWidget(tool_btn)

        # creating first tab
        self.add_new_tab(qurl="None", label='Homepage')

        # showing all the components
        self.show()
        self.setWindowIcon(QIcon("static/devsat.png"))
        # setting window title
        self.setWindowTitle("    DEVSAT")

    # method for adding new tab
    def add_new_tab(self, qurl="None", label="Blank"):

        # if url is blank
        if qurl == "None":
            db_res = self.conn.execute("select * from devsat where id=1")
            result = db_res.fetchall()
            self.db_result = result[0]
            if self.db_result[4] == "google":
                qurl = QUrl('http://www.google.com')
            else:
                qurl = QUrl('http://www.bing.com')
        else:

            qurl = QUrl(qurl)
        # creating a QWebEngineView object
        browser = QWebEngineView()

        # setting url to browser
        browser.setUrl(qurl)

        # setting tab index
        i = self.tabs.addTab(browser, label)
        self.tabs.setCurrentIndex(i)

        # link=browser.page().contextMenuData().linkUrl()
        # adding action to the browser when url is changed
        # update the url
        browser.urlChanged.connect(lambda qurl, browser=browser:
                                   self.update_urlbar(qurl, browser))

        # adding action to the browser when loading is finished
        # set the tab title
        browser.loadFinished.connect(lambda _, i=i, browser=browser:
                                     self.tabs.setTabText(i, browser.page().title()))

        browser.loadFinished.connect(lambda: self.savehistory(browser.page().url(), browser.page().title()))

        browser.page().profile().downloadRequested.connect(self._downloadRequested)

    # when double clicked is pressed on tabs
    def tab_open_doubleclick(self, i):

        # checking index i.e
        # No tab under the click
        if i == -1:
            # creating a new tab
            self.add_new_tab()

    # wen tab is changed
    def current_tab_changed(self, i):

        try:
            # get the curl
            qurl = self.tabs.currentWidget().url()

            # update the url
            self.update_urlbar(qurl, self.tabs.currentWidget())

            # update the title
            self.update_title(self.tabs.currentWidget())
        except Exception:
            pass

    # when tab is closed
    def close_current_tab(self, i):

        # if there is only one tab
        if self.tabs.count() < 2:
            # do nothing
            return

        # else remove the tab
        rwidget = self.tabs.widget(i)
        if rwidget:
            rwidget.deleteLater()
        self.tabs.removeTab(i)

    # method for updating the title
    def update_title(self, browser):

        # if signal is not from the current tab
        if browser != self.tabs.currentWidget():
            # do nothing
            return

        # get the page title
        title = self.tabs.currentWidget().page().title()

        # set the window title
        self.setWindowTitle("% s - DEVSAT" % title)

    # action to go to home
    def navigate_home(self):
        try:
            db_res = self.conn.execute("select * from devsat where id=1")
            result = db_res.fetchall()
            self.db_result = result[0]
            if self.db_result[4] == "google":
                # go to google
                qurl = QUrl('http://www.google.com')
            else:
                # go to bing
                qurl = QUrl('http://www.bing.com')

            self.tabs.currentWidget().setUrl(QUrl("http://www.google.com"))
        except:
            pass

    # method for navigate to url
    def navigate_to_url(self):

        # get the line edit text
        # convert it to QUrl object
        q = QUrl(self.urlbar.text())

        # if scheme is blank
        if q.scheme() == "":
            # set scheme
            q.setScheme("https")

        # set the url
        try:
            self.tabs.currentWidget().setUrl(q)
        except:
            pass

    # method to update the url
    def update_urlbar(self, q, browser=None):

        # If this signal is not from the current tab, ignore
        if browser != self.tabs.currentWidget():
            return

        # set text to the url bar
        self.urlbar.setText(q.toString())

        # set cursor position
        self.urlbar.setCursorPosition(0)

    def tabReload(self):
        try:
            self.tabs.currentWidget().reload()
        except:
            pass

    def tabforward(self):
        try:
            self.tabs.currentWidget().forward()
        except:
            pass

    def tabback(self):
        try:
            self.tabs.currentWidget().back()
        except:
            pass

    def loadstop(self):
        try:
            self.tabs.currentWidget().stop()
        except:
            pass

    def savehistory(self, url, title):

        url = url.toString()

        restricted = ["http://www.google.com", "https://www.google.com/", "http://www.bing.com",
                      "https://www.bing.com/"]
        # storing history

        if url not in restricted:
            # print(url)
            # print(title)
            date = str(datetime.datetime.now().date())
            self.conn.execute("insert into history values(null,'{}','{}','{}')".format(title, url, date))
            self.conn.commit()

    def print(self):
        printer = QPrinter()

        painter = QtGui.QPainter()
        # setting capture window
        painter.begin(printer)
        screen = self.grab()
        painter.drawPixmap(0, 0, self.rect().height(), self.rect().width(), screen)
        painter.end()

    def save_file(self):

        url = self.tabs.currentWidget().url().toString()

        html = requests.get(url).text

        filename, _ = QFileDialog.getSaveFileName(self, "Save Page As", "",
                                                  "Hypertext Markup Language (*.htm *html);;"
                                                  "All files (*.*)")
        try:
            if filename:
                with io.open(filename, "w", encoding="utf-8") as f:
                    f.write(html)
        except Exception as e:
            print(e)

    def _downloadRequested(self, item):  # QWebEngineDownloadItem
        try:
            try:
                initDownPath = os.path.join(os.getenv('USERPROFILE'), 'Downloads')
                my_dir = QFileDialog.getExistingDirectory(
                    self,
                    "select a download location",
                    initDownPath,
                    QFileDialog.ShowDirsOnly
                )
            except:
                pass

            # my_dir = my_dir.replace("/", "\\")
            # if my_dir[-1] != "\\":
            #     my_dir = my_dir + "\\" + item.downloadFileName()
            # else:
            #     my_dir = my_dir + item.downloadFileName()
            #
            # print(my_dir)
            # item.setPath(my_dir)
            print('downloading to', item.path())
            item.accept()
            self.down.setText("downloaded... " + item.downloadFileName())

            fpath = "/".join(str(item.path()).split("/")[:-1])
            self.openpath = fpath
            item.finished.connect(self.download_finished)
        except Exception as e:
            print(str(e))

    def download_finished(self):
        print("successfully downloaded")
        self.opend.setText("show in folder")

    def openloc(self):
        if (self.openpath != ""):
            print("path ready")
            path = self.openpath
            if 'darwin' in sys.platform:
                subprocess.check_call(['open', '--', path])
            elif 'linux' in sys.platform:
                subprocess.check_call(['xdg-open', path])
            elif 'win' in sys.platform:
                webbrowser.open(path)

    def settingui(self, index=1):

        Dialog = QtWidgets.QWidget()
        ui = Ui_Dialog()
        if index > 0:
            ui.setupUi(Dialog, self, index)

        i = self.tabs.addTab(ui.thiswindow, "settings")
        self.tabs.setCurrentIndex(i)

# settings dialog classes

class Ui_Dialog(object):
    def setupUi(self, Dialog, browser, tabindex=1):
        self.tabWidget = QtWidgets.QTabWidget(Dialog)
        self.tabWidget.setGeometry(QtCore.QRect(50, 100, 1200, 500))
        self.tabWidget.setTabShape(QtWidgets.QTabWidget.Rounded)
        self.tabWidget.setObjectName("tabWidget")
        self.tabWidget.setStyleSheet(u"background-color:rgb(50, 50, 50); color:white;")
        self.browser = browser
        # loading css file
        f = open("static/dialog.css", "r")
        Dialog.setStyleSheet(f.read())

        # connecting database
        self.conn = sqlite3.connect('static/devsat.db')
        # fetching data from database
        db_res = self.conn.execute("select * from devsat where id=1")
        result = db_res.fetchall()
        self.db_result = result[0]

        # devsat logo
        self.imagedev = QtWidgets.QLabel(Dialog)
        self.imagedev.setGeometry(700, 10, 100, 100)
        self.imagedev.setAutoFillBackground(False)
        self.imagedev.setText("")
        self.imagedev.setPixmap(QtGui.QPixmap("static/devsat.png"))
        self.imagedev.setScaledContents(True)
        self.imagedev.setWordWrap(False)
        self.imagedev.setOpenExternalLinks(False)
        self.imagedev.setObjectName("devsat logo")

        # devsat branding
        self.devlab = QtWidgets.QLabel(Dialog)
        self.devlab.setGeometry(785, 40, 200, 40)
        self.devlab.setObjectName("settings")
        self.devlab.setText("DevSAT")
        self.devlab.setObjectName("head")
        self.devlab.setStyleSheet("color:#33cccc; letter-spacing:2px; font-size:40px;")

        # settings dialog heading
        self.set = QtWidgets.QLabel(Dialog)
        self.set.setGeometry(70, 50, 200, 30)
        self.set.setObjectName("settings")
        self.set.setText("Settings")
        self.set.setObjectName("head")
        self.set.setStyleSheet("color:#ffcc99; letter-spacing:2px; font-size:25px;")

        # personalized tab
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")

        # calling scrollbar

        # new tab lebel
        self.newtab = QtWidgets.QLabel(self.tab)
        self.newtab.setGeometry(QtCore.QRect(100, 10, 250, 40))
        self.newtab.setObjectName("label_2")
        self.newtab.setText("Set personalized newtab page")
        self.newtab.setObjectName("medium")

        # custom new Tab button
        self.radioButton = QtWidgets.QRadioButton(self.tab)
        self.radioButton.setGeometry(QtCore.QRect(200, 50, 200, 40))
        self.radioButton.setObjectName("radioButton")
        self.radioButton.setText("Default newTab")

        self.radioButton_2 = QtWidgets.QRadioButton(self.tab)
        self.radioButton_2.setGeometry(QtCore.QRect(200, 90, 200, 40))
        self.radioButton_2.setObjectName("radioButton_2")
        self.radioButton_2.setText("Custom newtab")

        self.label_2 = QtWidgets.QLabel(self.tab)
        self.label_2.setGeometry(QtCore.QRect(220, 160, 160, 30))
        self.label_2.setObjectName("label_2")
        self.label_2.setText("custom tab page url :")
        self.label_2.setObjectName("medium")

        self.lineEdit = QtWidgets.QLineEdit(self.tab)
        self.lineEdit.setGeometry(QtCore.QRect(380, 150, 400, 40))
        self.lineEdit.setObjectName("lineEdit")
        self.lineEdit.setPlaceholderText("https://google.com")

        # chech newtab button condition
        if self.db_result[3] == "":
            self.radioButton.setChecked(True)
        else:
            self.radioButton_2.setChecked(True)
            self.lineEdit.setText(self.db_result[3])

        self.label_3 = QtWidgets.QLabel(self.tab)
        self.label_3.setGeometry(100, 240, 170, 50)
        self.label_3.setObjectName("label_2")
        self.label_3.setText("Default Search Engine")
        self.label_3.setObjectName("medium")

        self.frame1 = QtWidgets.QFrame(self.tab)
        self.frame1.setGeometry(QtCore.QRect(100, 280, 300, 100))

        self.frame1.setObjectName("frame")

        self.google = QtWidgets.QRadioButton(self.frame1)
        self.google.setGeometry(QtCore.QRect(160, 10, 200, 40))
        self.google.setObjectName("google")
        self.google.setText("Google")

        self.bing = QtWidgets.QRadioButton(self.frame1)
        self.bing.setGeometry(QtCore.QRect(160, 60, 200, 40))
        self.bing.setObjectName("bing")
        self.bing.setText("Bing")

        # chech newtab button condition
        if self.db_result[4].lower() == "google":
            self.google.setChecked(True)
        else:
            self.bing.setChecked(True)

        self.save = QtWidgets.QPushButton(self.tab)
        self.save.setGeometry(QtCore.QRect(300, 400, 200, 50))
        self.save.setObjectName("save")
        self.save.setText("Save")
        self.save.setStyleSheet("color:cyan; font-size:18px; background:black; border-radius:8px;")
        self.save.clicked.connect(self.settab)
        self.save.setCursor(QCursor(QtCore.Qt.PointingHandCursor))

        # adding to widget
        self.tabWidget.addTab(self.tab, "personalization")

        # profile page

        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")

        # labeling heading
        self.label = QtWidgets.QLabel(self.tab_2)
        self.label.setGeometry(QtCore.QRect(50, 20, 300, 40))
        self.label.setObjectName("label")
        self.label.setText("Your Profile")
        self.label.setObjectName("head")

        # creating frame
        self.frame = QtWidgets.QFrame(self.tab_2)
        self.frame.setGeometry(QtCore.QRect(50, 80, 700, 200))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.frame.setObjectName("frame")
        self.frame.setStyleSheet("background-color:rgb(100,100,100);")

        # setting user image
        self.image = QtWidgets.QLabel(self.frame)
        self.image.setGeometry(20, 20, 150, 150)
        self.image.setAutoFillBackground(False)
        self.image.setText("")
        self.image.setPixmap(QtGui.QPixmap("static/user.png"))
        self.image.setScaledContents(True)
        self.image.setWordWrap(False)
        self.image.setOpenExternalLinks(False)
        self.image.setObjectName("user image")

        # placing username
        self.user = QtWidgets.QLabel(self.frame)
        self.user.setGeometry(QtCore.QRect(180, 40, 300, 30))
        self.user.setObjectName("username")
        self.user.setText(self.db_result[1])
        self.user.setObjectName("head")

        # creating login feedback label
        self.feed = QtWidgets.QLabel(self.frame)
        self.feed.setGeometry(QtCore.QRect(420, 45, 63, 20))
        self.feed.setObjectName("username")
        self.feed.setObjectName("badge")

        # placing email
        self.useremail = QtWidgets.QLabel(self.frame)
        self.useremail.setGeometry(QtCore.QRect(185, 70, 300, 40))
        self.useremail.setObjectName("username")
        self.useremail.setText(self.db_result[2])
        self.useremail.setObjectName("medium")

        # sign-up condition
        if self.db_result[2] == "":
            self.signup = QtWidgets.QPushButton(self.frame)
            self.signup.setGeometry(QtCore.QRect(500, 60, 150, 50))
            self.signup.setObjectName("pushButton_2")
            self.signup.setText("Sign in")
            self.signup.setObjectName("sign up")
            self.signup.setStyleSheet("background-color:#b3ffb3; color:black;")
            self.signup.clicked.connect(self.login)
            self.signup.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
            self.feed.setStyleSheet("background-color:red; color:black;")
            self.feed.setText("logged out")

        else:
            self.signout = QtWidgets.QPushButton(self.frame)
            self.signout.setGeometry(QtCore.QRect(500, 60, 150, 50))
            self.signout.setObjectName("pushButton_2")
            self.signout.setText("Sign out")
            self.signout.setObjectName("sign out")
            self.signout.setStyleSheet("border:1px solid white; border-radius:8px; color:white; font-size:20px;")
            self.signout.clicked.connect(self.logout)
            self.feed.setStyleSheet("background-color:green; color:black;")
            self.signout.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
            self.feed.setText("logged in")

        self.label = QtWidgets.QLabel(self.tab_2)
        self.label.setGeometry(QtCore.QRect(70, 10, 55, 16))
        self.label.setObjectName("label")
        self.label.setText("")

        self.pushButton = QtWidgets.QPushButton(self.tab_2)
        # self.pushButton.setGeometry(QtCore.QRect(180, 320, 200, 30))
        self.pushButton.move(100, 320)
        self.pushButton.setObjectName("pushButton")
        self.pushButton.setText("Manage Account")
        self.pushButton.setObjectName("profile")
        self.pushButton.setCursor(QCursor(QtCore.Qt.PointingHandCursor))

        self.pushButton_2 = QtWidgets.QPushButton(self.tab_2)
        # self.pushButton_2.setGeometry(QtCore.QRect(180, 350, 200, 30))
        self.pushButton_2.move(100, 350)
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.setText("Sync")
        self.pushButton_2.setObjectName("profile")
        self.pushButton_2.setCursor(QCursor(QtCore.Qt.PointingHandCursor))

        self.pushButton_3 = QtWidgets.QPushButton(self.tab_2)
        # self.pushButton_3.setGeometry(QtCore.QRect(180, 350, 200, 30))
        self.pushButton_3.move(100, 380)
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_3.setText("Personal Info")
        self.pushButton_3.setObjectName("profile")
        self.pushButton_3.setCursor(QCursor(QtCore.Qt.PointingHandCursor))

        self.pushButton_4 = QtWidgets.QPushButton(self.tab_2)
        # self.pushButton_4.setGeometry(QtCore.QRect(180, 350, 200, 30))
        self.pushButton_4.move(100, 410)
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_4.setText("Profile preferences")
        self.pushButton_4.setObjectName("profile")
        self.pushButton_4.setCursor(QCursor(QtCore.Qt.PointingHandCursor))

        # pushing tab_2 to widget
        self.tabWidget.addTab(self.tab_2, "Profiles")

        # privacy page
        self.privacy = QtWidgets.QWidget()
        self.privacy.setObjectName("privacy")

        self.label0 = QtWidgets.QLabel(self.privacy)
        self.label0.setGeometry(50, 20, 300, 40)
        self.label0.setObjectName("label")
        self.label0.setText("Privacy & Services")
        self.label0.setObjectName("head")

        # privacy logo
        self.prilogo = QtWidgets.QLabel(self.privacy)
        self.prilogo.setGeometry(50, 80, 170, 100)
        self.prilogo.setAutoFillBackground(False)
        self.prilogo.setText("")
        self.prilogo.setPixmap(QtGui.QPixmap("static/privacy.png"))
        self.prilogo.setScaledContents(True)
        self.prilogo.setWordWrap(False)
        self.prilogo.setOpenExternalLinks(False)
        self.prilogo.setObjectName("devsat logo")

        # promice label
        name = self.db_result[1].split()
        self.abtpri = QtWidgets.QLabel(self.privacy)
        self.abtpri.setGeometry(210, 100, 500, 30)
        self.abtpri.setObjectName("settings")
        self.abtpri.setText("Hey " + name[0] + ", We value your privacy.")
        self.abtpri.setObjectName("head")
        self.abtpri.setStyleSheet("color:white; letter-spacing:1px; font-size:22px;")

        # policy version
        self.policy = QtWidgets.QLabel(self.privacy)
        self.policy.setGeometry(210, 130, 500, 60)
        self.policy.setObjectName("settings")
        self.policy.setText(
            "We always protect and respect your privacy,\nwhile giving you the transparency and control you deserve.")
        self.policy.setObjectName("small")
        self.policy.setStyleSheet("color:white; letter-spacing:1px; font-size:14px")

        # privacy logo
        self.track = QtWidgets.QLabel(self.privacy)
        self.track.setGeometry(100, 200, 600, 250)
        self.track.setAutoFillBackground(False)
        self.track.setText("")
        self.track.setPixmap(QtGui.QPixmap("static/policy.JPG"))
        self.track.setScaledContents(True)
        self.track.setWordWrap(False)
        self.track.setOpenExternalLinks(False)
        self.track.setObjectName("devsat logo")

        # pushing privacy to widget
        self.tabWidget.addTab(self.privacy, "Privacy Services")

        # about page
        self.about = QtWidgets.QWidget()
        self.about.setObjectName("devsat")

        # adding heading
        self.label = QtWidgets.QLabel(self.about)
        self.label.setGeometry(50, 20, 300, 40)
        self.label.setObjectName("label")
        self.label.setText("About")
        self.label.setObjectName("head")

        # devsat logo
        self.devlogo = QtWidgets.QLabel(self.about)
        self.devlogo.setGeometry(50, 80, 50, 50)
        self.devlogo.setAutoFillBackground(False)
        self.devlogo.setText("")
        self.devlogo.setPixmap(QtGui.QPixmap("static/devsat.png"))
        self.devlogo.setScaledContents(True)
        self.devlogo.setWordWrap(False)
        self.devlogo.setOpenExternalLinks(False)
        self.devlogo.setObjectName("devsat logo")

        # devsat branding
        self.abtdev = QtWidgets.QLabel(self.about)
        self.abtdev.setGeometry(100, 85, 200, 20)
        self.abtdev.setObjectName("settings")
        self.abtdev.setText("DevSAT Browser")
        self.abtdev.setObjectName("head")
        self.abtdev.setStyleSheet("color:white; letter-spacing:1px; font-size:22px;")

        # devsat version
        self.version = QtWidgets.QLabel(self.about)
        self.version.setGeometry(100, 110, 500, 20)
        self.version.setObjectName("settings")
        self.version.setText(build_version)
        self.version.setObjectName("head")
        self.version.setStyleSheet("color:white; letter-spacing:1px; font-size:14px")

        # devsat credential
        self.cred = QtWidgets.QLabel(self.about)
        self.cred.setGeometry(100, 200, 700, 20)
        self.cred.setObjectName("settings")
        self.cred.setText(
            "This browser is made possible by the Pyqt5 open source project and other open source Libraries.")
        self.cred.setObjectName("small")

        # devsat credential
        self.team = QtWidgets.QLabel(self.about)
        self.team.setGeometry(600, 400, 300, 20)
        self.team.setObjectName("settings")
        self.team.setText("- Built By DevSAT Team")
        self.team.setObjectName("small")
        self.team.setStyleSheet("color:cyan; font-size:18px")

        # pushing privacy to widget
        self.tabWidget.addTab(self.about, "About DevSAT")

        # building history page
        self.history = QtWidgets.QWidget()
        self.history.setObjectName("devsat")

        # adding heading
        self.hislabel = QtWidgets.QLabel(self.history)
        self.hislabel.setGeometry(50, 20, 300, 40)
        self.hislabel.setObjectName("label")
        self.hislabel.setText("History")
        self.hislabel.setObjectName("head")

        # scroll bar
        history = self.conn.execute("select * from history;")
        result = history.fetchall()
        self.formLayout = QFormLayout()
        groupBox = QGroupBox("Your last 7 days history")
        if len(result) > 1:
            result = result[-1::-1]
        rowcount = 0
        for data in result:
            rowcount += 1

            url = data[2]
            title = data[1]
            if len(title) > 15:
                title = title[:15]
            his = QPushButton("  " + title)
            his.setIcon(QIcon("static/external-link.png"))
            his.setStyleSheet("font-size:18px; color:yellowgreen; padding:10px;")
            his.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
            his.clicked.connect(lambda x, url=url: self.openhist(url))

            date = QLabel(data[3])
            date.setStyleSheet("font-size:18px; color:white; padding-top:10px;")

            id = data[0]
            delhis = QPushButton(" Clear history ")
            delhis.setStyleSheet("font-size:18px; color:red; padding:10px;")
            delhis.setIcon(QIcon("static/trash.png"))
            delhis.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
            delhis.clicked.connect(lambda x, id=id, rowcount=rowcount: self.delhist(id, rowcount))

            widget = QWidget()
            layout_h = QHBoxLayout(widget)
            layout_h.addWidget(his)
            layout_h.addWidget(delhis)
            self.formLayout.addRow(date, widget)

        groupBox.setLayout(self.formLayout)
        scroll = QScrollArea()
        scroll.setWidget(groupBox)
        scroll.setWidgetResizable(True)
        scroll.setFixedHeight(350)
        self.frame2 = QtWidgets.QFrame(self.history)
        self.frame2.setGeometry(50, 80, 800, 360)
        self.frame2.setObjectName("frame2")

        layout = QVBoxLayout(self.frame2)

        layout.addWidget(scroll)

        # adding cleare all butten

        self.cls = QPushButton(self.history)
        self.cls.setText(" clear all")
        self.cls.setIcon(QIcon("static/trash.png"))
        self.cls.setGeometry(640, 30, 200, 40)
        # self.cls.setStyleSheet("font-size:18px; color:red; padding:10px;")
        self.cls.setStyleSheet("QPushButton::hover{background-color:red;color:white;font-size:18px;padding:10px;}")
        self.cls.setObjectName("clearall")
        self.cls.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
        self.cls.clicked.connect(lambda x, rowcount=rowcount: self.clsall(rowcount))

        # pushing history to widget
        self.tabWidget.addTab(self.history, "history")

        # adding download page
        self.download = QtWidgets.QWidget()
        self.download.setObjectName("download")
        # adding head label
        self.dlabel = QtWidgets.QLabel(self.download)
        self.dlabel.setGeometry(50, 20, 300, 40)
        self.dlabel.setObjectName("label")
        self.dlabel.setText("Downloads")
        self.dlabel.setObjectName("head")

        # pushing history to widget
        self.tabWidget.addTab(self.download, "Downloads")

        # self.retranslateUi(Dialog)
        self.tabWidget.setCurrentIndex(tabindex)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

        # seting tab icon

        self.tabWidget.setTabIcon(0, QIcon("static/custom.png"))
        self.tabWidget.setTabIcon(1, QIcon("static/profile.png"))
        self.tabWidget.setTabIcon(2, QIcon("static/shild.png"))
        self.tabWidget.setTabIcon(3, QIcon("static/devsat1.png"))

        self.thiswindow = Dialog

    def openhist(self, url):

        self.browser.add_new_tab(qurl=url)

    def delhist(self, id, rowcount):
        try:
            self.conn.execute("delete from history where id ={}".format(id))
            self.conn.commit()
            self.formLayout.removeRow(rowcount - 1)
        except Exception as e:
            pass

    def clsall(self, rowcount):
        try:
            self.conn.execute("delete from history;")
            self.conn.commit()
            for i in range(rowcount):
                self.formLayout.removeRow(i)

        except:
            pass

    def settab(self):

        if self.db_result[3] == "" and self.radioButton.isChecked():
            pass
        elif self.db_result[3] != "" and self.radioButton_2.isChecked():
            pass
        elif self.db_result[3] == "" and self.radioButton_2.isChecked():
            self.conn.execute("update devsat set newtab='{}' where id=1".format(self.lineEdit.text()))
        elif self.db_result[3] != "" and self.radioButton.isChecked():
            self.conn.execute("update devsat set newtab='' where id=1")

        if self.google.isChecked():
            self.conn.execute("update devsat set search='google' where id=1")
        else:
            self.conn.execute("update devsat set search='bing' where id=1")

        self.conn.commit()

    def login(self):

        winlog = QtWidgets.QDialog()
        ui = ui_winlog(winlog)

        winlog.show()
        winlog.exec_()

    def logout(self):
        self.conn.execute("update devsat set email='' where id=1;")
        self.conn.commit()

class ui_winlog(object):

    def __init__(self, dialog):
        dialog.setGeometry(200, 200, 1000, 600)
        # dialog.setFixedWidth(500)
        # dialog.setFixedHeight(650)
        dialog.setWindowTitle("Sign-in")
        dialog.setWindowIcon(QIcon("static/user-green.png"))

        f = open("static/login.css", "r")

        dialog.setStyleSheet(f.read())
        dialog.setObjectName("head")

        self.initui(dialog)

    def initui(self, dialog):
        pass
        self.leftf = QtWidgets.QLabel(dialog)
        self.leftf.setGeometry(0, 0, 500, 600)
        loginbg = ["loginbg.jpg", "loginbg2.jpg", "loginbg3.jpg", "loginbg4.jpg"]
        bg = random.randint(0, 3)
        self.leftf.setStyleSheet("background-image:url('static/{}');".format(loginbg[bg]))
        # head image
        self.image = QtWidgets.QLabel(dialog)
        self.image.setGeometry(120, 150, 260, 190)
        self.image.setAutoFillBackground(False)
        self.image.setText("")
        self.image.setPixmap(QtGui.QPixmap("static/devsat.png"))
        self.image.setScaledContents(True)
        self.image.setWordWrap(False)
        self.image.setOpenExternalLinks(False)
        self.image.setObjectName("image")

        # # heading text
        self.head = QtWidgets.QLabel(dialog)
        self.head.move(90, 380)
        self.head.setText("WELCOME BACK")
        self.head.setObjectName("head")
        self.head.adjustSize()

        # # heading text right
        self.headr = QtWidgets.QLabel(dialog)
        self.headr.move(590, 50)
        self.headr.setText("Sign in/Sign up")
        self.headr.setObjectName("headr")
        self.headr.adjustSize()

        # input fields
        self.nameinput = QLineEdit(dialog)
        self.nameinput.setGeometry(550, 180, 400, 50)
        self.nameinput.setPlaceholderText(" UserName")

        # input email
        self.emailinput = QLineEdit(dialog)
        self.emailinput.setGeometry(550, 250, 400, 50)
        self.emailinput.setPlaceholderText(" Email")
        #
        # input password
        self.passinput = QLineEdit(dialog)
        self.passinput.setGeometry(550, 320, 400, 50)
        self.passinput.setPlaceholderText(" password")
        self.passinput.setEchoMode(QLineEdit.Password)
        #
        # radio option1
        self.radiobtn1 = QRadioButton(dialog)
        self.radiobtn1.setGeometry(600, 400, 100, 20)
        self.radiobtn1.setText("Sign-in")
        self.radiobtn1.adjustSize()
        self.radiobtn1.setChecked(True)

        # radio option2
        self.radiobtn2 = QRadioButton(dialog)
        self.radiobtn2.setGeometry(800, 400, 100, 20)
        self.radiobtn2.setText("Register")
        self.radiobtn2.adjustSize()
        #
        # submit button
        self.b1 = QtWidgets.QPushButton(dialog)
        self.b1.setText("SUBMIT")
        self.b1.setObjectName("btn1")
        self.b1.move(690, 450)
        self.b1.adjustSize()
        self.b1.clicked.connect(self.submit)
        self.b1.setCursor(QCursor(QtCore.Qt.PointingHandCursor))
        #
        # feedback lable
        self.feed = QLabel(dialog)
        self.feed.setGeometry(500, 550, 500, 50)
        self.feed.setText("")
        self.feed.setObjectName("feedback")

    def submit(self):
        conn = sqlite3.connect('static/devsat.db')
        # fetching data from database

        data = {}
        data["username"] = self.nameinput.text()
        data["email"] = self.emailinput.text()
        data["passward"] = self.passinput.text()
        if self.radiobtn1.isChecked():
            data["action"] = "sign-in"

            if data["username"] == "" or data["passward"] == "":
                self.feed.setStyleSheet("  background-color: yellowgreen;")
                self.feed.setText("Crendtial error")
            else:
                db_res = conn.execute("select * from admin")
                result = db_res.fetchall()

                if len(result) == 0:
                    self.feed.setStyleSheet("  background-color: yellowgreen;")
                    self.feed.setText("register Now")
                else:

                    cred = conn.execute("select * from admin where id=1")
                    res = cred.fetchall()[0]
                    if res[2] == data["email"] and res[3] == data["passward"]:
                        conn.execute("update devsat set email='{}' where id=1".format(data["email"]))
                        conn.commit()
                        self.feed.setStyleSheet("  background-color: yellowgreen;")
                        self.feed.setText("logged in")
                    else:
                        self.feed.setStyleSheet("  background-color: yellowgreen;")
                        self.feed.setText("wrong credential")

        else:
            data["action"] = "register"
            if data["username"] == "" or data["passward"] == "" or data["email"] == "":
                self.feed.setStyleSheet("  background-color: yellowgreen;")
                self.feed.setText("Crendtial error")

            else:
                db_res = conn.execute("select * from admin where id=1")
                result = db_res.fetchall()
                if len(result) == 0:
                    conn.execute("INSERT INTO admin VALUES(1,'{}','{}','{}')".format(data["username"], data["email"],
                                                                                data["passward"]))
                    conn.execute(
                        "update devsat set user='{}',email='{}' where id=1".format(data["username"], data["email"]))
                    self.feed.setStyleSheet("  background-color: yellowgreen;")
                    conn.commit()
                    self.feed.setText("Successfully registered")
                else:
                    self.feed.setStyleSheet("  background-color: yellowgreen;")
                    self.feed.setText("alreary registered")

        # if data["username"] == "" or data["passward"]=="":
        #     self.feed.setStyleSheet("  background-color: yellowgreen;")
        #     self.feed.setText("Error happen")
        # else:
        #     self.feed.setStyleSheet("  background-color: yellowgreen;")
        #     self.feed.setText("success")

class welcome(QMainWindow):
    def __init__(self):
        super().__init__()

        # <MainWindow Properties>
        self.setFixedSize(600, 400)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setCursor(QCursor(QtCore.Qt.PointingHandCursor))

        self.bg = QLabel(self)
        self.bg.setGeometry(0, 0, 600, 400)
        self.bg.setStyleSheet("background-image:url('static/welcomebg.jpg')")

        self.image = QtWidgets.QLabel(self)
        self.image.setGeometry(150, 130, 300, 210)
        self.image.setAutoFillBackground(False)
        self.image.setText("")
        self.image.setPixmap(QtGui.QPixmap("static/devsat.png"))
        self.image.setScaledContents(True)
        self.image.setWordWrap(False)
        self.image.setOpenExternalLinks(False)
        self.image.setObjectName("image")
        self.image.setStyleSheet("background-image:None;")

        bar = QProgressBar(self)
        x = 25
        # setting geometry to progress bar
        bar.setGeometry(0, 390, 650, 10)
        # setting value to progress bar
        bar.setValue(x)
        self.show()
        for i in range(3):
            x += 25

            bar.setValue(x)
            time.sleep(1)

# creating a PyQt5 application
app = QApplication(sys.argv)

# setting name to the application
welcome = welcome()
welcome.close()

# creating MainWindow object
window = BrowserWindow()

# loop
sys.exit(app.exec_())


import RedQueen
from threading import Thread

class Player():
    def __init__(self, color):
        self.color = color
        self.type = type(self).__name__
        self.moving = False
        self.moveCoordinates = None
    def move(self, party):
        pass
    @staticmethod
    def createPlayer(type, color):
        if type == 'local':
            return LocalPlayer(color)
        elif type == 'cpu':
            return CPUPlayer(color)
        elif type == 'network':
            return NetworkPlayer(color)
        else:
            return None
class LocalPlayer(Player):
    def __init__(self, color):
        super().__init__(color)
    def move(self, party):
        if self.moving:
            if self.moveCoordinates == None:
                return None
            else:
                self.moving = False
                return self.moveCoordinates
        else:
            self.moveCoordinates = None
            self.moving = True
            return None
class CPUPlayer(Player):
    def __init__(self, color):
        super().__init__(color)
        self.bot = RedQueen.Bot(color)
    def move(self, party):
        if self.moving:
            if self.moveCoordinates == None:
                return None
            else:
                self.moving = False
                return self.moveCoordinates
        else:
            self.moveCoordinates = None
            self.moving = True
            thread = Thread(target=self.startBot, args=(party, 3))
            thread.start()
            return None
    def startBot(self, party, depth):
        self.moveCoordinates = self.bot.lookAhead(party, depth)
class NetworkPlayer(Player):
    def __init__(self, color):
        super().__init__(color)


import numpy as np
import torch
import math
import trimesh
import glob
import torch
import os

# All lengths are in mm and rotations in radians

class BarrettLayer(torch.nn.Module):
    def __init__(self, device='cpu'):
        # The forward kinematics equations implemented here are from https://support.barrett.com/wiki/Hand/280/KinematicsJointRangesConversionFactors
        super().__init__()
        self.Aw = torch.tensor(0.001 * 25, dtype=torch.float32, device=device)
        self.A1 = torch.tensor(0.001 * 50, dtype=torch.float32, device=device)
        self.A2 = torch.tensor(0.001 * 70, dtype=torch.float32, device=device)
        self.A3 = torch.tensor(0.001 * 50, dtype=torch.float32, device=device)
        self.Dw = torch.tensor(0.001 * 76, dtype=torch.float32, device=device)
        self.Dw_knuckle = torch.tensor(0.001 * 42, dtype=torch.float32, device=device)
        self.D3 = torch.tensor(0.001 * 9.5, dtype=torch.float32, device=device)
        self.phi2 = torch.tensor(0, dtype=torch.float32, device=device)
        self.phi3 = torch.tensor(0 * math.radians(42), dtype=torch.float32, device=device)
        self.pi_0_5 = torch.tensor(math.pi / 2, dtype=torch.float32, device=device)
        self.device = device
        self.meshes = self.load_meshes()
        self.palm = self.meshes["palm_280"][0]
        self.knuckle = self.meshes["knuckle"][0]
        self.finger = self.meshes["finger"][0]
        self.finger_tip = self.meshes["finger_tip"][0]

        self.gripper_faces = [
            self.meshes["palm_280"][1], self.meshes["knuckle"][1], self.meshes["finger"][1],
            self.meshes["finger_tip"][1]
        ]
        self.vertice_face_areas = [
            self.meshes["palm_280"][2], self.meshes["knuckle"][2], self.meshes["finger"][2],
            self.meshes["finger_tip"][2]
        ]
        self.num_vertices_per_part = [
            self.meshes["palm_280"][0].shape[0], self.meshes["knuckle"][0].shape[0], self.meshes["finger"][0].shape[0],
            self.meshes["finger_tip"][0].shape[0]
        ]
        # r and j are used to calculate the forward kinematics for the barrett Hand's different fingers
        self.r = [-1, 1, 0]
        self.j = [1, 1, -1]

    def load_meshes(self):
        mesh_path = os.path.dirname(os.path.realpath(__file__)) + "/../meshes/barrett_hand/*"
        mesh_files = glob.glob(mesh_path)
        mesh_files = [f for f in mesh_files if os.path.isfile(f)]
        meshes = {}
        for mesh_file in mesh_files:
            name = os.path.basename(mesh_file)[:-4]
            mesh = trimesh.load(mesh_file)
            triangle_areas = trimesh.triangles.area(mesh.triangles)
            vert_area_weight = []
            for i in range(mesh.vertices.shape[0]):
                vert_neighour_face = np.where(mesh.faces == i)[0]
                vert_area_weight.append(1000000*triangle_areas[vert_neighour_face].mean())
            temp = torch.ones(mesh.vertices.shape[0], 1).float()
            meshes[name] = [
                torch.cat((torch.FloatTensor(mesh.vertices), temp), dim=-1).to(self.device),
                torch.LongTensor(mesh.faces).to(self.device), torch.FloatTensor(vert_area_weight).to(self.device),
                torch.FloatTensor(mesh.vertex_normals)
            ]
        return meshes

    def forward(self, pose, theta):
        """[summary]
        Args:
            pose (Tensor (batch_size x 4 x 4)): The pose of the base link of the hand as a translation matrix.
            theta (Tensor (batch_size x 7)): The seven degrees of freedome of the Barrett hand. The first column specifies the angle between
            fingers F1 and F2,  the second to fourth column specifies the joint angle around the proximal link of each finger while the fifth
            to the last column specifies the joint angle around the distal link for each finger

       """
        batch_size = pose.shape[0]
        rot_z_90 = torch.eye(4, device=self.device)

        rot_z_90[1, 1] = -1
        rot_z_90[2, 3] = -0.001 * 79
        rot_z_90 = rot_z_90.repeat(batch_size, 1, 1)
        pose = torch.matmul(pose, rot_z_90)
        palm_vertices = self.palm.repeat(batch_size, 1, 1)
        palm_vertices = torch.matmul(pose,
                                     palm_vertices.transpose(2, 1)).transpose(
                                         1, 2)[:, :, :3]
        # The second dimension represents the number of joints for the fingers which are stored as: finger1 joint1, finger1 joint2, ..., finger 3 joint 2
        joints = torch.zeros((batch_size, 6, 4, 4), device=self.device)

        all_knuckle_vertices = torch.zeros(
            (batch_size, 2, self.knuckle.shape[0], 3), device=self.device)

        knuckle_vertices = self.knuckle.repeat(batch_size, 1, 1)

        all_finger_vertices = torch.zeros(
            (batch_size, 3, self.finger.shape[0], 3), device=self.device)
        all_finger_tip_vertices = torch.zeros(
            (batch_size, 3, self.finger_tip.shape[0], 3), device=self.device)

        finger_vertices = self.finger.repeat(batch_size, 1, 1)
        finger_tip_vertices = self.finger_tip.repeat(batch_size, 1, 1)
        for i in range(3):
            Tw1 = self.forward_kinematics(
                self.r[i] * self.Aw, torch.tensor(0, dtype=torch.float32, device=self.device), self.Dw,
                self.r[i] * theta[:, 0] - (math.pi / 2) * self.j[i],
                batch_size)
            T12 = self.forward_kinematics(self.A1, torch.tensor(math.pi / 2, dtype=torch.float32, device=self.device),
                                          0, self.phi2 + theta[:, i + 1],
                                          batch_size)
            T23 = self.forward_kinematics(self.A2, torch.tensor(math.pi, dtype=torch.float32, device=self.device), 0,
                                          self.phi3 - theta[:, i + 4], batch_size)

            if i is 0 or i is 1:
                Tw_knuckle = self.forward_kinematics(
                    self.r[(i+1) % 2] * self.Aw, torch.tensor(0, dtype=torch.float32, device=self.device), self.Dw_knuckle,
                    -1*(self.r[i] * theta[:, 0] - (math.pi / 2) * self.j[i]),
                    batch_size)
                pose_to_Tw_knuckle = torch.matmul(pose, Tw_knuckle)
                all_knuckle_vertices[:, i] = torch.matmul(pose_to_Tw_knuckle,
                                                          knuckle_vertices.transpose(2, 1)).transpose(1, 2)[:, :, :3]
            pose_to_T12 = torch.matmul(torch.matmul(pose, Tw1), T12)
            all_finger_vertices[:, i] = torch.matmul(
                pose_to_T12,
                finger_vertices.transpose(2, 1)).transpose(1, 2)[:, :, :3]
            pose_to_T23 = torch.matmul(pose_to_T12, T23)
            all_finger_tip_vertices[:, i] = torch.matmul(
                pose_to_T23,
                finger_tip_vertices.transpose(2, 1)).transpose(1, 2)[:, :, :3]
            joints[:, 2 * i] = pose_to_T12
            joints[:, 2 * i + 1] = pose_to_T23
        return palm_vertices, all_knuckle_vertices, all_finger_vertices, all_finger_tip_vertices, joints

    def forward_kinematics(self, A, alpha, D, theta, batch_size=1):
        c_theta = torch.cos(theta)
        s_theta = torch.sin(theta)
        c_alpha = torch.cos(alpha)
        s_alpha = torch.sin(alpha)
        l_1_to_l = torch.zeros((batch_size, 4, 4), device=self.device)
        l_1_to_l[:, 0, 0] = c_theta
        l_1_to_l[:, 0, 1] = -s_theta
        l_1_to_l[:, 0, 3] = A
        l_1_to_l[:, 1, 0] = s_theta * c_alpha
        l_1_to_l[:, 1, 1] = c_theta * c_alpha
        l_1_to_l[:, 1, 2] = -s_alpha
        l_1_to_l[:, 1, 3] = -s_alpha * D
        l_1_to_l[:, 2, 0] = s_theta * s_alpha
        l_1_to_l[:, 2, 1] = c_theta * s_alpha
        l_1_to_l[:, 2, 2] = c_alpha
        l_1_to_l[:, 2, 3] = c_alpha * D
        l_1_to_l[:, 3, 3] = 1
        return l_1_to_l


import parsing
from threading import *
from time import sleep
from concurrent.futures import ThreadPoolExecutor
import datetime
URLS =['https://europharma.kz/catalog/lekarstvennye-sredstva?segment=available',
       'https://europharma.kz/catalog/vitaminy-i-bady?segment=available',
       'https://europharma.kz/catalog/izdelia-med-naznacenia?segment=available',
       'https://europharma.kz/catalog/mat-i-ditya?segment=available',
       'https://europharma.kz/catalog/krasota-i-gigiena?segment=available']

"""parsing url"""
# for index in range(0, len(URLS)):
#     filename =f"urls_sub_cat_{index}.txt"
#     print(index)
#     parsing.get_list_of_urls(filename)

conn = parsing.connection
cur = conn.cursor()
cur2 =conn.cursor()

# file = open("city.txt", encoding='utf-8', mode='r')
# for line in file:
#     x = line.split(",")
#     print(x[0])
#     query=f"INSERT INTO CITY(city, url) VALUES ('{x[0]}', '{x[1]}')"
#     cur.execute(query)
#     conn.commit()

"""parsing content"""
# # cur.execute("select url from urls")
# col = cur.fetchall()
# print(len(col))
# count=0
#
# for c in col:
#             html=parsing.get_html(c[0])
#             x = c[0].split(".kz/")
#             parsing.get_content_of_items(html, x[1])
#             count +=1
#             print(count)

query = f"SELECT city, url FROM CITY where id>4"

cur.execute(query)
city_row = cur.fetchall()
q2 = f"SELECT id, url from product"
cur.execute(q2)
product_row = cur.fetchall()

def write_item_url_to_txt(city, filename):
    file = open(filename, encoding='utf-8', mode ='a')
    for product in product_row:
        u = city[1].replace("\n", "")
        url = u + product[1]
        text = f"{city[0]},{url},{product[0]}\n"
        file.write(text)

def inserting(line):
            r = line.split(",")
            url =r[1]
            html = parsing.get_html(url)
            if html:
                list = parsing.get_price(html)
                try:
                    q3 = f"INSERT INTO price (city, product_id, price, availability, url, date ) VALUES ('{r[0]}', {r[2]},'{list[0]}','{list[1]}', '{url}', '{datetime.date.today()}')"
                    cur.execute(q3)
                    conn.commit()
                    print('Inserted')
                except Exception as ex:
                    print(ex)

with open("url_items.txt", encoding="utf-8", mode='r') as file:
    # for line in file:
    #     inserting(line)
    with ThreadPoolExecutor(max_workers=100) as executor:
        t1 = [executor.submit(inserting, line) for line in file]

# filename = "url_items.txt"
#
# for r in city_row:
#     write_item_url_to_txt(r, filename)

# with ThreadPoolExecutor(max_workers=4) as executor:
#     t1 = executor.submit(execute_query_1, query1)
    # t2 = executor.submit(execute_query_2, query2)

# #
# t1.start()
# t2.start()
# t3.start()
# t4.start()


import argparse

def parse_opts():
    parser = argparse.ArgumentParser(description='this is Train options')
    parser.add_argument('--debug', dest='debug', action='store_true', help='Debug mode')
    parser.add_argument('--no-debug', dest='debug', action='store_false', help='Debug mode')
    parser.set_defaults(debug=True)
    parser.add_argument(
        '--tensorboard',
        default='TEST',
        type=str,
        help='Model name about tensorboard (resnet50-2layers-LSTM-> r50-2lLSTM| )')
    parser.add_argument(
        '--encoder_model',
        default='',
        type=str,
        help='encoder model path')
    parser.add_argument(
        '--flag',
        default='No',
        type=str,
        help='Flag infomation about tensorboard')

    parser.add_argument(
        '--model_name',
        default='resnet50-lstm',
        type=str,
        help='Model name, examples:(resnet50-lstm | resnet50-gru')
    args = parser.parse_args()

    return args


# ✅ Save user input to file
file_name = 'example2.txt'

with open(file_name, 'w', encoding='utf-8') as my_file:
    my_file.write(input('Your message: '))

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

# ✅ Take filename and contents of file from user input

file_name = input('Filename with extension, e.g. example.txt: ')

with open(file_name, 'w', encoding='utf-8') as my_file:
    my_file.write(input('Your message: '))


lentokentat = {}

kysymys = ()
while kysymys != '':
    kysymys = input('Haluatko hakea, vai tallentaa tietoa? (H/T)')
    if kysymys == '':
        break
    while kysymys not in ['h', 'H', 't', 'T']:
        print('Ei hyväksytty.')
        kysymys = input('Haluatko hakea, vai tallentaa tietoa? (H/T)')
        if kysymys == '':
            break

    if kysymys in ['t', 'T']:
        talletus1 = input('Syötä ICAO-koodi: ')
        talletus2 = input('Syötä lentokentän nimi: ')
        lentokentat[talletus1] = talletus2
        print('Talletus onnistui.')

    elif kysymys in ['h', 'H'] and lentokentat == {}:
        print('Ei tallennettuja lentokenttiä.')

    elif kysymys in ['h', 'H']:
        haku = input('Syötä ICAO-koodi: ')
        while haku not in lentokentat:
            print('ICAO-koodi ei löydy.')
            haku = input('Syötä ICAO-koodi: ')
        print(f'Hakemasi kenttä on: {lentokentat[haku]}')


def pushNumtoEnd(li, num):
    count = 0
    for i in range(len(li)):
        if li[i] != num:
            temp = li[count]
            li[count] = li[i]
            li[i] = temp
            count += 1
    print(li)

li = [5, 6, 2, 3, 6, 3, 9, 3, 4, 5, 6]
pushNumtoEnd(li, 3)

def noOfWordsInString(strig):
    li = strig.lower().split(" ")
    d = {}
    for strig1 in li:
        if strig1 not in d.keys():
            d[strig1] = 1
        else:
            d[strig1] = d[strig1] + 1
    for keys, values in d.items():
        print(str(keys) + " count is " + str(values))

noOfWordsInString("This this is is a new word in sentence")

def isAnagram(s1, s2):
    li1 = [x for x in s1.lower()]
    li2 = [x for x in s2.lower()]
    if sorted(li1) == sorted(li2):
        print(True)
    else:
        print(False)

isAnagram("Listen", "Silent")

def isStringPalindrome(st):
    if st.lower() == st[::-1].lower():
        print(True)
    else:
        print(False)

isStringPalindrome("Tenet")

def isNumPalindrome(num):
    num1 = num
    temp = 0
    while num != 0:
        temp = (num % 10) + (temp * 10)
        num = num // 10
    if temp == num1:
        print(True)
    else:
        print(False)

isNumPalindrome(1214)

def longestSubStringWithoutRepeating(str1):
    longestSubStr = ""
    longestSubstrLen = 0
    li = [x for x in str1]
    d = {}
    for i in range(len(li)):
        if li[i] not in d:
            d[li[i]] = i
        else:
            i = d[li[i]]
            d.clear()
        if longestSubstrLen < len(d):
            longestSubStr = str(d.keys())
            longestSubstrLen = len(d)
    print(longestSubStr)
    print(longestSubstrLen)

longestSubStringWithoutRepeating("GEEKSFORGEEKS")

def reverseList(string):
    li = [x for x in string.lower()]
    string1 = ""
    l, r = 0, len(li) - 1
    while l < r:
        temp = li[l]
        li[l] = li[r]
        li[r] = temp
        l += 1
        r -= 1

    for x in li:
        string1 += str(x)
    print(string1)

reverseList("dfafadf")

def reveseStringPreservingSpecialCharSpace(string):
    li = [x for x in string.lower()]
    string1 = ""
    l, r = 0, len(li) - 1
    while l < r:
        if not li[l].isalpha():
            l += 1
        elif not li[r].isalpha():
            r -= 1
        else:
            temp = li[l]
            li[l] = li[r]
            li[r] = temp
            l += 1
            r -= 1
    for x in li:
        string1 += str(x)
    print(string1)

reveseStringPreservingSpecialCharSpace("dfaf%^&* fdafaf  adf")

def intersectionString(str1, str2):
    str3 = ""
    s1 = set(str1)
    s2 = set(str2)
    s3 = set()
    print(s1.intersection(s2))
    for i in range(len(str1)):
        for j in range(len(str2)):
            if str1[i] == str2[j]:
                s3.add(str1[i])

    intersect = [x for x in str2 if x in str1]
    print(str(s3))
    print(set(intersect))

intersectionString("Hello", "How are you")

def exceptionHandling():
    a = 7
    b = 0
    try:
        print(a / b)
    except ArithmeticError:
        print("Cannot Divide by 0")
    finally:
        print("This will be printed")

exceptionHandling()


# Algorithm 2.4: Merge Sort2 (Enhanced Merge Sort)
def mergeSort2(S, low, high):
  if (low < high):
    mid = (low + high) // 2
    mergeSort2(S, low, mid)
    mergeSort2(S, mid + 1, high)
    print(S[low:high+1])
    merge2(S, low, mid, high)

# Algorithm 2.5: Merge2 (Enhanced Merge)
def merge2(S, low, mid, high):
  i = low
  j = mid + 1
  U = []
  while (i <= mid and j <= high):
    if (S[i] < S[j]):
      U.append(S[i])
      i += 1
    else:
      U.append(S[j])
      j += 1
  if (i <= mid):
    U += S[i : mid + 1]
  else:
    U += S[j : high + 1]
  for k in range(low, high + 1):
    S[k] = U[k - low]

S = [27, 10, 13, 20, 25, 13, 15, 22]
mergeSort2(S, 0, len(S) - 1)
print(S)

'''
추가적으로 만들어지는 원소의 수를 약 n개 정도로 절약

Divid-and-conquer :분할정복 알고리즘 설계 기법을 배움
  1. 이진 탐색
  2. 합병 정렬
  이진 탐색은 반을 취하고 나머지는 버리는 것을 반복
  합병 정렬은 반을 쪼개며 들어가며 양쪽을 해결하며 하나씩 합병
  따라서 시간복잡도는 이진탐색이 더 우수
'''


from monitor import *
import logging as lg
import os
from datetime import datetime
class LoggingMonitor(Monitor):

    def __init__(self, period=10):
        super(LoggingMonitor, self).__init__("LoggingMonitor", period)
        # Put any iniitialization code here
        # BEGIN STUDENT CODE
        self.logger = lg.getLogger("Terry_Monitor")
        self.filename = None
        # END STUDENT CODE

    def perceive(self):
        # BEGIN STUDENT CODE

        self.sensordata =  self.sensordata
        self.time = self.sensordata['unix_time']
        self.actuator_state =  self.actuator_state
        self.clock_time = datetime.utcfromtimestamp(self.time)
        # END STUDENT CODE

    def clock_time(self,unix):
        return datetime.utcfromtimestamp(unix)

    def monitor(self):
        folder = "allLogs"
        if not os.path.exists(folder):
            os.makedirs(folder)

        if (not self.filename):
            self.filename = os.path.join(folder,f"log{int(self.time)}.txt")
        with open(self.filename, 'a') as f:
            time = str(self.clock_time)
            f.write(time)
            for key in self.sensordata:
                f.write(f", {key}: {self.sensordata[key]}")
            for key in self.actuator_state:
                f.write(f", {key}: {self.actuator_state[key]}")
            f.write("\n")


import pandas as pd

trainingSet = pd.read_csv("./data/train.csv")
testingSet = pd.read_csv("./data/test.csv")

predictionSet = pd.merge(trainingSet, testingSet, left_on='Id', right_on='Id')
print(predictionSet.columns)

predictionSet = predictionSet.drop(columns=['Score_x'])
predictionSet = predictionSet.rename(columns={'Score_y': 'Score'})

print(predictionSet.columns)
predictionSet.to_csv("./data/prediction.csv", index=False)

X_train = trainingSet[trainingSet['Score'].notnull()]
print(trainingSet.shape)
print(X_train.shape)
X_train.to_csv("./data/X_train.csv", index=False)


from nltk.tokenize import sent_tokenize, word_tokenize
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from datetime import datetime
from nltk.stem import PorterStemmer
import csv
import nltk
import re
import pandas as pd
# import matplotlib.pyplot as plt
import string

nltk.download('stopwords')

# from nltk.sentiment import Sentim1entIntensityAnalyzer

nltk.download('punkt')
nltk.download('wordnet')
# nltk.download()

# defs
contractions = {
    "ain't": "am not",
    "aren't": "are not",
    "can't": "cannot",
    "can't've": "cannot have",
    "'cause": "because",
    "could've": "could have",
    "couldn't": "could not",
    "couldn't've": "could not have",
    "didn't": "did not",
    "doesn't": "does not",
    "don't": "do not",
    "hadn't": "had not",
    "hadn't've": "had not have",
    "hasn't": "has not",
    "haven't": "have not",
    "he'd": "he would",
    "he'd've": "he would have",
    "he'll": "he will",
    "he'll've": "he will have",
    "he's": "he is",
    "how'd": "how did",
    "how'd'y": "how do you",
    "how'll": "how will",
    "how's": "how is",
    "i'd": "i would",
    "i'd've": "i would have",
    "i'll": "i will",
    "i'll've": "i will have",
    "i'm": "i am",
    "i've": "i have",
    "isn't": "is not",
    "it'd": "it would",
    "it'd've": "it would have",
    "it'll": "it will",
    "it'll've": "it will have",
    "it's": "it is",
    "let's": "let us",
    "ma'am": "madam",
    "mayn't": "may not",
    "might've": "might have",
    "mightn't": "might not",
    "mightn't've": "might not have",
    "must've": "must have",
    "mustn't": "must not",
    "mustn't've": "must not have",
    "needn't": "need not",
    "needn't've": "need not have",
    "o'clock": "of the clock",
    "oughtn't": "ought not",
    "oughtn't've": "ought not have",
    "shan't": "shall not",
    "sha'n't": "shall not",
    "shan't've": "shall not have",
    "she'd": "she would",
    "she'd've": "she would have",
    "she'll": "she will",
    "she'll've": "she will have",
    "she's": "she is",
    "should've": "should have",
    "shouldn't": "should not",
    "shouldn't've": "should not have",
    "so've": "so have",
    "so's": "so is",
    "that'd": "that had",
    "that'd've": "that would have",
    "that's": "that is",
    "there'd": "there would",
    "there'd've": "there would have",
    "there's": "there is",
    "they'd": "they would",
    "they'd've": "they would have",
    "they'll": "they will",
    "they'll've": "they will have",
    "they're": "they are",
    "they've": "they have",
    "to've": "to have",
    "wasn't": "was not",
    "we'd": "we would",
    "we'd've": "we would have",
    "we'll": "we will",
    "we'll've": "we will have",
    "we're": "we are",
    "we've": "we have",
    "weren't": "were not",
    "what'll": "what will",
    "what'll've": "what will have",
    "what're": "what are",
    "what's": "what is",
    "what've": "what have",
    "when's": "when is",
    "when've": "when have",
    "where'd": "where did",
    "where's": "where is",
    "where've": "where have",
    "who'll": "who will",
    "who'll've": "who will have",
    "who's": "who has",
    "who've": "who have",
    "why's": "why is",
    "why've": "why have",
    "will've": "will have",
    "won't": "will not",
    "won't've": "will not have",
    "would've": "would have",
    "wouldn't": "would not",
    "wouldn't've": "would not have",
    "y'all": "you all",
    "y'all'd": "you all would",
    "y'all'd've": "you all would have",
    "y'all're": "you all are",
    "y'all've": "you all have",
    "you'd": "you would",
    "you'd've": "you would have",
    "you'll": "you will",
    "you'll've": "you will have ",
    "you're": "you are",
    "you've": "you have"
}

def tokenizer(document):

    # define regular expression patterns
    #     punctuation_pattern = re.compile(r'\w+|[^\w\s]') # matches all punctuations
    words = re.findall(r"[a-zA-Z]+(?:'[a-zA-Z]+)*", document)
    tokens = []
    for word in words:
        # Normalize clitics
        if "'" in word and word in contractions:
            tokens.extend(contractions[word.lower()].split())
        # Convert word-ending apostrophe
        elif word.endswith("'"):
            tokens.append(word[:-1] + " 's")
        # Otherwise, add the word as a token
        else:
            tokens.append(word)
    return tokens

def lemmatize_tokens(tokens):
    lemmatizer = WordNetLemmatizer()
    lemmatized_tokens = []
    for token in tokens:
        lemmatized_token = lemmatizer.lemmatize(token)
        lemmatized_tokens.append(lemmatized_token)
    return lemmatized_tokens

def remove_punctuations(text):
    # get a string of all punctuation characters
    punctuations = string.punctuation

    # iterate over each character in the text and check if it's a punctuation mark
    # if it's not a punctuation mark, add it to the result string
    result = ''
    for char in text:
        if char not in punctuations:
            result += char

    return result

custom_stopwords = set(stopwords.words('english')) - set(
    ['not', 'no', 'never', 'nothing', 'nobody', 'nowhere', 'neither', 'nor', 'none', 'but', 'except', 'without', 'hardly'])

def remove_stopwords(sents, sw):
    filtered_tokens = [w for w in sents if w not in sw]
    return filtered_tokens

hashmap = {}

def increase_count(token):
    if token in hashmap:
        hashmap[token] = hashmap[token] + 1
    else:
        hashmap[token] = 1

def sentiment(review, positive_words, negative_words):
    positive_counter = 0
    negative_counter = 0
    count = 0

    for word in review:
        if word in positive_words:
            positive_counter = positive_counter+1
            count += 1
        elif word in negative_words:
            negative_counter = negative_counter+1
            count += 1

    if (count == 0):
        return [0, 0]

    words_count = count

    # mostly positive
    pos = positive_counter/words_count
    neg = negative_counter/words_count

    positive_counts = (round(pos + 0.005, 2))
    negative_counts = (round(neg + 0.005, 2))

    return [positive_counts, negative_counts]

def calc_no_of_rows():
    num_rows = 0

    for row in open("reviews.csv1"):
        num_rows += 1

    return num_rows

def write_metrics_to_csv(data, file):
    writer = csv.writer(file)

    writer.writerow([data[0], data[1]])

def main():
    sum = 0
    no_of_reviews = 0
    game_info = []  # Contains id at index 0 and game_review in words at index 1
    crr_game_id = 0

    pos_sent = open("positive.txt").read()
    positive_words = pos_sent.split('\n')

    neg_sent = open("negative.txt").read()
    negative_words = neg_sent.split('\n')

    with open('reviews.csv1', 'r') as file:
        with open('metrics.csv', 'a', newline='') as file1:
            reader = csv.reader(file)
            lines = calc_no_of_rows()

            i = 0

            for document in reader:
                try:
                    if ((str(document[0]))[0:len(str(crr_game_id))] != crr_game_id or i == lines-1):
                        if (no_of_reviews > 0):
                            review_metric = sum/no_of_reviews
                            game_info.append([crr_game_id, review_metric])
                            no_of_reviews = 0
                            sum = 0
                            write_metrics_to_csv(
                                [crr_game_id, review_metric], file1)
                            print(crr_game_id, review_metric)

                        if (i == lines-1):
                            return game_info
                        crr_game_id = document[0]

                    no_of_reviews += 1
                    sents = tokenizer(document[1])
                    sents = [
                        token for token in sents if token not in string.punctuation]
                    lt = lemmatize_tokens(sents)
                    st = remove_stopwords(lt, custom_stopwords)

                    values = sentiment(st, positive_words, negative_words)
                    sum += values[0]-values[1]
                except Exception:
                    i += 1

res = main()
print(res)


from xml.etree import ElementTree
import feedparser
import urllib2
import StringIO
import gzip
import calendar
import requests

class HtmlInterface:
    def __init__(self):
        self.excluded_urls = \
        ['http://www.philosophyofinformation.net/publications/pdf/htdpi.pdf']

    def get_url(self, content_url):
        if content_url not in self.excluded_urls:
            #print "getting url: %s" % content_url
            self.html = self.get_webpage(content_url)
            return self.html

    def get_webpage(self,  url):
        try:
            r = requests.get(url, timeout=5)
            return r.content
        except requests.exceptions.ReadTimeout:
            return False
        except requests.exceptions.ConnectionError:
            return False

class OpmlInterface:
    def __init__(self, opml):
        self.opml_file = opml
        self.site_feeds = []
        with open(self.opml_file, 'rt') as f:
            self.opml = ElementTree.parse(f)

    def get_section(self, section):
        self.site_feeds = []
        for node in self.opml.getiterator('outline'):
            for name, value in sorted(node.attrib.items()):
                if name == 'text' and value == section:
                    for specific_node in node.getiterator():
                        title = specific_node.attrib.get('text')
                        url = specific_node.attrib.get('xmlUrl')
                        if name and url:
                            self.site_feeds.append((title, url))
        return self.site_feeds

    def iterate(self, section):
        for title, url in self.get_section(section):
            rss = RssInterface(url)
            blog = rss.parse_rss()
            for entry in blog.entries:
                if hasattr(entry, 'description'):
                    if hasattr(entry, 'published'):
                        date = self.cleanup_date(entry.published)
                    else:
                        date = "01 Jan 0001"
                    yield blog.feed.title,\
                        entry.title,\
                        entry.link,\
                        entry.description,\
                        date

    def cleanup_date(self, date):
        if " " in date:
            new_date = date.split(" ")
            return " ".join(new_date[1:4])
        elif "T" in date:
            temp = date.split("T")
            new = temp[0].split("-")
            temp = new[2], calendar.month_name[int(new[1])][:3], new[0]
            return " ".join(temp)

class RssInterface:
    def __init__(self, rss_input):
        self.rss_input = rss_input

    def parse_rss(self):
        return feedparser.parse(self.rss_input)


def minion_game(string):
    vowel = "AEIOU"
    st = 0
    kv = 0
    x = len(string)
    for i in range(x):
        if string[i] in vowel:
            kv += x - i
        else:
            st += x - i
    if st > kv:
        print("Stuart", str(st))
    elif kv > st:
        print("Kevin", str(kv))
    else:
        print("Draw")

if __name__ == '__main__':
    s = input()
    minion_game(s)


import pandas as pd
import numpy as np
import requests
from bs4 import BeautifulSoup
import string
import time
from datetime import datetime
import dateutil.relativedelta
from google.cloud import storage
import sys
import alpaca_trade_api as tradeapi
import json

if(len(sys.argv) < 2):
    print("Invalid number of inputs. Expected 1 int: time period in months ")
    exit(1)

storage_client = storage.Client()
bucket = storage_client.get_bucket('ai-final-project')
blob = bucket.blob('alpaca-key-ID.txt')
blob2 = bucket.blob('alpaca-key.txt')
api_id = blob.download_as_string()[:-1].decode('utf-8')
api_key = blob2.download_as_string()[:-1].decode('utf-8')
api = tradeapi.REST(
    key_id=api_id,
    secret_key=api_key,
    api_version='v2',
    base_url='https://paper-api.alpaca.markets')

def get_symbol_list():
    return [
        each.symbol for each in api.list_assets(status='active')
        if each.exchange == 'NASDAQ' or each.exchange == 'NYSE']

# Get the historical dates you need.
to_date = datetime.strptime('2020-03-03', '%Y-%m-%d')
from_date = to_date - dateutil.relativedelta.relativedelta(months=int(sys.argv[1]))
from_fmt = from_date.strftime('%Y-%m-%d')
to_fmt = to_date.strftime('%Y-%m-%d')

symbols = get_symbol_list()
data_list = []
for each in symbols:
    url = fr"https://api.polygon.io/v2/aggs/ticker/{each}/range/1/day"\
            fr"/{from_fmt}/{to_fmt}"

    params = {
        'apiKey': api_id
    }

    request = requests.get(
        url=url,
        params=params
    ).json()

    if(request.get('resultsCount') == 0):
        continue

    data_list.append(request)
    time.sleep(.5)

# Create a list for each data point and loop through the json, adding the data
# to the lists
symbl_l, open_l, high_l, low_l, close_l = [], [], [], [], []
volume_l, date_l = [], []

for data in data_list:
    try:
        symbol_name = data['ticker']
    except KeyError:
        pass
    if symbol_name is None:
        continue
    try:
        for each in data['results']:
            symbl_l.append(symbol_name)
            open_l.append(each['o'])
            high_l.append(each['h'])
            low_l.append(each['l'])
            close_l.append(each['c'])
            volume_l.append(each['v'])
            date_l.append(each['t'])
    except KeyError:
        pass
    except TypeError:
        pass

# Create a datafrom from the lists
df = pd.DataFrame(
     {
        'symbol': symbl_l,
        'open': open_l,
        'high': high_l,
        'low': low_l,
        'close': close_l,
        'volume': volume_l,
        'date': date_l
    }
)

# Format the Dates
df['date'] = pd.to_datetime(df['date'], unit='ms')
df['date'] = df['date'].dt.strftime('%Y-%m-%d')
# Save to csv
df.to_csv(r'back_data.csv')


"""
# Definition for a Node.
class Node:
    def __init__(self, val):
        self.val = val
        self.neighbors = []
"""
class Solution:
    def cloneGraph(self, node: 'Node') -> 'Node':
        if not node: return None
        connection = {}
        stack = [node]
        new = Node(node.val)
        connection[id(node)] = new
        while not stack == []:
            cur = stack.pop()
            for nb in cur.neighbors:
                if id(nb) not in connection:
                    new = Node(nb.val)
                    connection[id(nb)] = new
                    stack.append(nb)
                connection[id(cur)].neighbors.append(connection[id(nb)])
        return connection[id(node)]


#!/usr/bin/python2

from astropy.io import fits
import numpy as np

ssem = fits.open('VI_SSEM_575273_2011-05-26T05:19:50.824_G475_MR_202166_Q2_hi.fits')
header1 = ssem[0].header
header1['NAXIS2'] = 1

fits.writeto('lastmedian.fits', np.median(ssem[0].data[0:80,:], axis=0)  ,header1)
mediannorm = [ i/np.max(ssem[0].data) for i in np.median(ssem[0].data[0:80,:],axis=0)]
fits.writeto('lastmediannorm.fits', mediannorm  ,header1)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
.. $Id$
"""

from __future__ import division
from __future__ import print_function
from __future__ import absolute_import

from zope import component

from zope.intid.interfaces import IIntIdRemovedEvent

from zope.lifecycleevent.interfaces import IObjectAddedEvent
from zope.lifecycleevent.interfaces import IObjectModifiedEvent

from nti.dataserver.interfaces import IThreadable
from nti.dataserver.interfaces import IDeletedObjectPlaceholder

from nti.graphdb import create_job
from nti.graphdb import get_graph_db
from nti.graphdb import get_job_queue

from nti.graphdb.common import get_oid
from nti.graphdb.common import get_creator
from nti.graphdb.common import get_node_primary_key

from nti.graphdb.interfaces import IObjectProcessor
from nti.graphdb.interfaces import IPropertyAdapter

from nti.graphdb.relationships import Reply
from nti.graphdb.relationships import IsReplyOf

from nti.ntiids.ntiids import find_object_with_ntiid

logger = __import__('logging').getLogger(__name__)

def remove_node(db, label, key, value):
    result = False
    node = db.get_indexed_node(label, key, value)
    if node is not None:
        db.delete_node(node)
        logger.debug("Node %s deleted", node)
        result = True
    return result

def remove_reply_relationship(db, key, value):
    rel_type = str(Reply())
    for rel in db.get_indexed_relationships(key, value):
        if str(rel.type) == rel_type:
            db.delete_relationship(rel)
            logger.debug("ReplyTo relationship %s deleted", rel)

def remove_threadable(db, label, key, value):
    remove_reply_relationship(db, key, value)
    remove_node(db, label, key, value)

def proces_threadable_removed(db, threadable):
    pk = get_node_primary_key(threadable) if threadable is not None else None
    if pk is not None:
        queue = get_job_queue()
        job = create_job(remove_threadable, db=db,
                         label=pk.label,
                         key=pk.key,
                         value=pk.value)
        queue.put(job)

@component.adapter(IThreadable, IIntIdRemovedEvent)
def _threadable_removed(threadable, unused_event):
    db = get_graph_db()
    if db is not None:
        proces_threadable_removed(db, threadable)

def delete_inReplyTo_relationship(db, oid):
    threadable = find_object_with_ntiid(oid)
    for rel in db.match(threadable, type_=IsReplyOf()) or ():
        db.delete_relationship(rel)

def add_inReplyTo_relationship(db, oid):
    result = False
    threadable = find_object_with_ntiid(oid)
    in_replyTo = threadable.inReplyTo if threadable is not None else None
    if in_replyTo is not None and not db.match(threadable, in_replyTo, IsReplyOf()):
        # create parent/child relationship
        rel = db.create_relationship(threadable, in_replyTo, IsReplyOf())
        logger.debug("IsReplyOf Relationship %s created", rel)
        # create author reply relationship
        from_author = get_creator(threadable)
        to_author = get_creator(in_replyTo)
        if to_author is not None and from_author is not None:
            # create a relationship between author and
            # the author being replied to
            properties = component.getMultiAdapter((from_author, threadable, Reply()),
                                                   IPropertyAdapter)
            rel = db.create_relationship(from_author, to_author, Reply(),
                                         properties=properties)
            logger.debug("ReplyTo relationship %s retreived/created", rel)
            result = True
    return result

def process_threadable_inReplyTo(db, threadable):
    oid = get_oid(threadable)
    queue = get_job_queue()
    job = create_job(add_inReplyTo_relationship, db=db, oid=oid)
    queue.put(job)

@component.adapter(IThreadable, IObjectAddedEvent)
def _threadable_added(threadable, unused_event):
    db = get_graph_db()
    if db is not None and threadable.inReplyTo:
        process_threadable_inReplyTo(db, threadable)

def modify_threadable(db, oid):
    threadable = find_object_with_ntiid(oid)
    if threadable is not None:
        pk = get_node_primary_key(threadable)
        if pk is not None:
            remove_reply_relationship(db, pk.key, pk.value)
        delete_inReplyTo_relationship(db, oid)
        add_inReplyTo_relationship(db, oid)

def proces_threadable_modified(db, threadable):
    oid = get_oid(threadable)
    if oid is not None:
        queue = get_job_queue()
        job = create_job(modify_threadable, db=db, oid=oid)
        queue.put(job)

@component.adapter(IThreadable, IObjectModifiedEvent)
def _threadable_modified(thread, unused_event):
    db = get_graph_db()
    if db is not None:
        if IDeletedObjectPlaceholder.providedBy(thread):
            proces_threadable_removed(db, thread)
        else:
            proces_threadable_modified(db, thread)

component.moduleProvides(IObjectProcessor)

def init(db, obj):  # pragma: no cover
    result = False
    if IThreadable.providedBy(obj) and obj.inReplyTo:
        process_threadable_inReplyTo(db, obj)
        result = True
    return result


def printrest(string,char,n):
    count=0
    for i in range(len(string)):
        if string[i]==char:
            count+=1
            if count==n:
                return string[i+1:]
    return "No string remaining"

print(printrest("this is a demo string","i",5))


#!/usr/bin/env python3

import design
import pytrellis
import database

def make_counter(des, name, size, clock, q):
    sum = None
    carry = None
    for i in range(size):
        slice_name = "{}[{}]".format(name, i)
        so_name = "{}[{}]_sum".format(name, i)
        co_name = "{}[{}]_carry".format(name, i)
        q_name = q[i]
        if i == 0:
            sum_lut = [1, 0] * 8
            carry_lut = [0, 1] * 8
            des.inst_slice(name=slice_name, a0=q_name, a1=q_name, f0=so_name, f1=co_name, clk=clock, q0=q_name,
                              params={
                                  "K0.INIT": sum_lut,
                                  "K1.INIT": carry_lut,
                                  "CEMUX": "1",
                                  "GSR": "DISABLED",
                                  "REG0.REGSET": "RESET"
                              })
        else:
            sum_lut = [1, 0, 0, 1] * 4
            carry_lut = [0, 1, 1, 1] * 4
            last_co = "{}[{}]_carry".format(name, i - 1)
            des.inst_slice(name=slice_name, a0=q_name, a1=q_name, b0=last_co, b1=last_co, f0=so_name, f1=co_name,
                              clk=clock, q0=q_name,
                              params={
                                  "K0.INIT": sum_lut,
                                  "K1.INIT": carry_lut,
                                  "CEMUX": "1",
                                  "GSR": "DISABLED",
                                  "REG0.REGSET": "RESET"
                              })

def make_bus(name, size):
    return ["{}[{}]".format(name, i) for i in range(size)]

def main():
    pytrellis.load_database(database.get_db_root())
    des = design.Design("LFE5U-45F")
    ctr_q = make_bus("Q", 8)
    des.router.bind_net_to_port("clk", "R62C89_JQ5") #random input! check!
    make_counter(des, "ctr", 8, "clk", ctr_q)
    des.make_bitstream("counter.bit")

if __name__ == "__main__":
    main()