# !/urs/bin/env python3
# -*- coding: utf-8 -*-

"""
Project: LAGOU Spider

@author: Troy
@email: ots239ltfok@gmail.com
"""
# 项目构架:
# p1: 依据搜索关键词 城市 职业, 爬取索引页, 解析并获取相关岗位url接连
# p2: 解析url链接, 获取数据
# p3: 存储到MongoDB

# 技术路径: requests urllib json re pq pymongo

import requests
from requests.exceptions import ConnectionError

from pyquery import PyQuery as pq
import urllib
import json
import pymongo
import numpy as np
import time
from config import *

client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]

proxy = None

def started_search_url(start_url, page):
    headers = {
        'Accept' : 'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding' : 'gzip, deflate, br',
        'Accept-Language' : 'zh-CN,zh;q=0.9',
        'Cache-Control' : 'no-cache',
        'Connection' : 'keep-alive',
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8',
        'Cookie' : COOKIE,
        'Host' : 'www.lagou.com',
        'Origin' : 'https://www.lagou.com',
        'Pragma' : 'no-cache',
        'Referer' : REFERER,
        'User-Agent' : 'Mozilla/5.0 Chrome/58.0.3029.81 Safari/537.36',
        }
    query_parameters = {
        'city' : CITY,
        'needAddtionalResult' : 'false',
        'isSchoolJob' : '0'
        }
    form_data = {
        'first' : 'false',
        'pn' : page,
        'kd' : KEYWORD
        }
    url = start_url + urllib.parse.urlencode(query_parameters)
    try:
        res = requests.post(url, headers=headers, data=form_data, allow_redirects=False)
        if res.status_code == 200:
            print('get succeed 200, page:', page)
            res.encoding = res.apparent_encoding
            res = json.loads(res.text)
            return res['content']['positionResult']['result']
        else:
            print('get failed, status code:', res.status_code)
            return None
    except ConnectionError as e:
        print('requests error:', e.args)
        return None

def get_base_data(data):
    try:
        companyId = data['companyId']
        companyFullName = data['companyFullName']
        companyShortName = data['companyShortName']
        companySize = data['companySize']
        positionAdvantage = data['positionAdvantage']
        city = data['city']
        latitude = data['latitude']
        longitude = data['longitude']
        stationname = data['stationname']
        subwayline = data['subwayline']
        financeStage = data['financeStage']
        positionName = data['positionName']
        firstType = data['firstType']
        secondType = data['secondType']
        workYear = data['workYear']
        education = data['education']
        district = data['district']
        salary = data['salary']
        positionLables = data['positionLables']
        positionId = data['positionId']
        html = request_index_search(positionId)
        position_description = parse_url_detail(html)

        result = {
            'companyId' : companyId,
            'companyFullName' : companyFullName,
            'companyShortName' : companyShortName,
            'positionAdvantage' : positionAdvantage,
            'latitude' : latitude,
            'longitude' : longitude,
            'stationname' : stationname,
            'subwayline' : subwayline,
            'financeStage' : financeStage,
            'positionName' : positionName,
            'firstType' : firstType,
            'secondType' : secondType,
            'workyear' : workYear,
            'education' : education,
            'district' : district,
            'salary' : salary,
            'positionLables' : positionLables,
            'positionId' : positionId,
            'position_description' : position_description
            }
        return result
    except TypeError :
        print('data get error')
        return None

def get_proxy():
    try:
        response = requests.get(PROXIES_URL)
        if response.status_code == 200:
            return response.text
        return None
    except ConnectionError:
        return None

def request_index_search(positionId):
    global proxy
    url = 'https://www.lagou.com/jobs/{}.html'.format(positionId)
    headers = {
        'Accept' : 'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding' : 'gzip, deflate, br',
        'Accept-Language' : 'zh-CN,zh;q=0.9',
        'Cache-Control' : 'no-cache',
        'Connection' : 'keep-alive',
        'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8',
        'Cookie' : COOKIE,
        'Host' : 'www.lagou.com',
        'Pragma' : 'no-cache',
        'User-Agent' : 'Mozilla/5.0 Chrome/58.0.3029.81 Safari/537.36'
        }
    try:
        if proxy:
            proxies = {
                'https' : 'https://' + proxy
                }
            res = requests.get(url, headers=headers, proxies=proxies, allow_redirects=False)

        else:
            res = requests.get(url, headers=headers, allow_redirects=False)
        print('Res.status_code:', res.status_code)
        if res.status_code == 200:
            print('get detail url succeed', url)
            res.encoding = res.apparent_encoding
            return res.text
        if res.status_code == 302:
            print('chunkError', res.status_code, url)
            proxy = get_proxy()
            if proxy:
                return request_index_search(positionId)
            else:
                print('proxy is fail')
                return None
    except ConnectionError as e:
        print('get url error:', e.args, url)
        return None

def parse_url_detail(html):
    doc = pq(html)
    position_description = doc('#job_detail > dd.job_bt > div').text()
    return position_description

def save_to_mongoDB(result):
    if db[MONGO_TABLE].update({'positionId' : result['positionId']}, {'$set' : result}, True):
        print('save to mongoDB Succeed', result)
    else:
        print('save to mongoDB Failed', result)

def main(pn):
    time.sleep(np.random.randint(0.1, 1))
    datas = started_search_url(start_url=START_URL, page=pn)
    print(datas)
    for data in datas:
        result = get_base_data(data)
        save_to_mongoDB(result)

if __name__ == '__main__':
    for pn in range(1, 20):
        main(pn)


from __future__ import division
import os
import re
import sys
import struct

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

def load(fname):
  color = None
  width = None
  height = None
  scale = None
  endian = None

  file = open(fname)
  header = file.readline().rstrip()
  if header == 'PF':
    color = True
  elif header == 'Pf':
    color = False
  else:
    raise Exception('Not a PFM file.')

  dim_match = re.match(r'^(\d+)\s(\d+)\s$', file.readline())
  if dim_match:
    width, height = map(int, dim_match.groups())
  else:
    raise Exception('Malformed PFM header.')

  scale = float(file.readline().rstrip())
  if scale < 0: # little-endian
    endian = '<'
    scale = -scale
  else:
    endian = '>' # big-endian

  data = np.fromfile(file, endian + 'f')
  shape = (height, width, 3) if color else (height, width)
  return np.flipud(np.reshape(data, shape)).astype(np.float32), scale

def save(fname, image, scale=1):
  file = open(fname, 'w')
  color = None

  if image.dtype.name != 'float32':
    raise Exception('Image dtype must be float32.')

  if len(image.shape) == 3 and image.shape[2] == 3: # color image
    color = True
  elif len(image.shape) == 2 or len(image.shape) == 3 and image.shape[2] == 1: # greyscale
    color = False
  else:
    raise Exception('Image must have H x W x 3, H x W x 1 or H x W dimensions.')

  file.write('PF\n' if color else 'Pf\n')
  file.write('%d %d\n' % (image.shape[1], image.shape[0]))

  endian = image.dtype.byteorder

  if endian == '<' or endian == '=' and sys.byteorder == 'little':
    scale = -scale

  file.write('%f\n' % scale)

  np.flipud(image).tofile(file)

def show(img):
  imgplot = plt.imshow(img.astype(np.float32), cmap='gray');
  plt.show();


# 반복문 : while문
# while 조건식 :
#       조건식이 참인 경우에 실행될 문장

# 1~100까지 홀수, 짝수의 합을 구하는 프로그램

i = 1; odd = even = 0
while i<=100:
    if i%2 == 0:
        even += i
    else:
        odd += i
    i += 1
print('1~100까지 홀수의 합 : ', odd)
print('1~100까지 짝수의 합 : ', even)


import sys

a, b, v = map(int, sys.stdin.readline().rstrip().split())

res = v //(a-b)
tempV = v %(a-b)

res = (v-a) // (a-b)
if (v-a) % (a-b) > 0:
    res += 2
else:
    res += 1
print(res)


def menu(water,milk,beans,cup,money):
    print("The Coffee machine has :")
    print(str(water)+" of water")
    print(str(milk)+" of milk")
    print(str(beans)+" of coffee beans")
    print(str(cup)+" of disposable cups")
    print(str(money)+" of money")

def fill(water,water_add,milk,milk_add,beans,beans_add,cup,cup_add):
    water = int(water) + int(water_add)
    milk = int(milk) + int(milk_add)
    beans = int(beans) + int(beans_add)
    cup = int(cup) + int(cup_add)
    return (water,milk,beans,cup)

def take(money):
    print("I gave you "+str(money))

def buy(water,water_used,milk,milk_used,beans,beans_used,cup,cup_used,money,money_take):
    water = int(water) - int(water_used)
    milk = int(milk) - int(milk_used)
    beans = int(beans) - int(beans_used)
    cup = int(cup) - int(cup_used)
    money = int(money) + int(money_take)
    return (water,milk,beans,cup,money)

y = 1

water = 400
milk = 540
beans = 120
cup = 9
money = 550

while y == 1:

    menu(water,milk,beans,cup,money)

    command = str(input("write action (buy, fill, take):\n> "))

    if "buy" in command:
        kind_of_coffee = str(input("What do you want to buy ? 1 - espresso , 2 - latte , 3 - capppuccino :\n> "))
        if "1" in kind_of_coffee:
            x = (buy(water,250,milk,0,beans,16,cup,1,money,4))
            menu((x[0]),(x[1]),(x[2]),(x[3]),(x[4]))
            water = (x[0])
            milk = (x[1])
            beans = (x[2])
            cup = (x[3])
            money = (x[4])

        elif "2" in kind_of_coffee:
            x = (buy(water,350,milk,75,beans,20,cup,1,money,7))
            menu((x[0]),(x[1]),(x[2]),(x[3]),(x[4]))
            water = (x[0])
            milk = (x[1])
            beans = (x[2])
            cup = (x[3])
            money = (x[4])

        elif "3" in kind_of_coffee:
            x = (buy(water,200,milk,100,beans,12,cup,1,money,6))
            menu((x[0]),(x[1]),(x[2]),(x[3]),(x[4]))
            water = (x[0])
            milk = (x[1])
            beans = (x[2])
            cup = (x[3])
            money = (x[4])

    elif "fill" in command:
        water_add = int(input("Write how many ml of water do you want add\n> "))
        milk_add = int(input("Write how many ml of milk do you want add\n> "))
        beans_add = int(input("Write how many grams of coffee beans do you want add\n> "))
        cup_add = int(input("Write how many disposable cups of coffee do you want add\n> "))
        x = fill(water, water_add, milk, milk_add, beans, beans_add, cup, cup_add)
        menu((x[0]),(x[1]),(x[2]),(x[3]),money)
        water = (x[0])
        milk = (x[1])
        beans = (x[2])
        cup = (x[3])
        money = (money)

    elif "take" in command:
        take(money)
        money = int(0)
        menu(water,milk,beans,cup,money)

    end = str(input("1 = exit / 2 = continue "))

    if "1" in end:
        break
    else:
        pass


#!/usr/bin/env python3
""" Import build-in and custom modules to check system utilization and connection"""
import shutil
import psutil
import network
site_name = "http://www.google.com"

# Verifies that there's enough free space on disk.
def check_disk_usage(disk):
    du = shutil.disk_usage(disk)
    free = du.free / du.total * 100
    return free > 20

# Verifies that there's enough unused CPU.
def check_cpu_usage():
    usage = psutil.cpu_percent(1)
    return usage < 75

# If there's not enough disk, or not enough CPU, print an error.
# Output information about connection.
if not check_disk_usage('/') or not check_cpu_usage():
    print("ERROR!")
elif network.check_localhost() and network.check_connectivity(site_name):
    print("Everything ok")
else:
    print("Network checks failed")


from Bio.Seq import Seq

def get_pattern_count(text, pattern):
    seq = Seq(text)
    return seq.count_overlap(pattern)

with open('rosalind_ba1e.txt') as file:
    genome = file.readline().rstrip()
    k, l, t = map(lambda x: int(x), file.readline().rstrip().split(' '))

genome_len = len(genome)
clump = []

for i in range(genome_len - l + 1):
    current_genome = genome[i:i+l]
    current_genome_len = len(current_genome)
    for j in range(current_genome_len - k + 1):
        pattern = current_genome[j:j+k]
        pattern_count = get_pattern_count(current_genome, pattern)
        if pattern_count >= t and pattern not in clump:
            clump.append(pattern)
            print(pattern)
output = ' '.join(clump)
print(output)
with open('output.txt', 'w') as file:
    file.write(output)

Lab Assignment - 1/chapter 1/ba1e Find Patterns Forming Clumps in a String.py


#A python program to find anagrams of a given word.
import sys

allLengthAnagrams = []

def findAnagrams(aWord) :
    anagrams = []
    if( len(aWord) == 2 ) :
        anagrams.append( aWord[0] + aWord[1] )
        anagrams.append( aWord[1] + aWord[0] )
        return anagrams

    for i in range(len(aWord)) :
        aLetter = aWord[i]
        restOfLetters = ""
        for j in range(len(aWord)) :
            if( i != j ) :
                restOfLetters = restOfLetters + aWord[j]
        anagramRest = findAnagrams(restOfLetters)
        for restWord in anagramRest :
            allLengthAnagrams.append(restWord)
            anagrams.append(aLetter + restWord)

    return anagrams

if( len(sys.argv) < 2 ) :
    print("How about a parameter there champ?")
    sys.exit(1)

aWord = sys.argv[1]

wordAnagrams = findAnagrams(aWord)
#print(wordAnagrams)
#print(allLengthAnagrams)
#print("There were", len(wordAnagrams), "found")

allLengthAnagrams = set(allLengthAnagrams)

allEnglishWords = []
with open("allwords.txt") as fIn:
    allEnglishWords = fIn.read().split(",")

englishAnagrams = []
for englishWord in allEnglishWords :
    if englishWord in allLengthAnagrams :
        englishAnagrams.append(englishWord)

print("Here is all english anagrams")
print(englishAnagrams)


import pandas as pd

def agg_count(row):
    count_x = getattr(row, 'Count_x', 0)
    count_y = getattr(row, 'Count_y', 0)
    count = getattr(row, 'Count', 0)

    row.Count = count + count_x + count_y
    return row

def top3(list_year, PATH):
    cols = ['Name', 'Gender', 'Count']
    names_all = None
    for year in list_year:
        names_year = pd.read_csv(PATH + 'yob{}.txt'.format(year), names=cols)
        if names_all is None:
            names_all = names_year
        else:
            names_all = pd.merge(names_all, names_year, on=['Name', 'Gender']).apply(agg_count, axis=1)
    names_all['total'] = names_all.sum(axis=1)
    #print(names_all)

    result = names_all.sort_values(by='total', ascending=False).head(3)
    return result['Name'].values

def dynamics(list_year, PATH):
    cols = ['Name', 'Gender', 'Count']
    names_all = None
    list_f = []
    list_m = []
    for year in list_year:
        names_year = pd.read_csv(PATH + 'yob{}.txt'.format(year), names=cols)
        f = names_year[names_year.Gender == 'F'].Count.sum()
        m = names_year[names_year.Gender == 'M'].Count.sum()
        list_f.append(f)
        list_m.append(m)
    result = {'F': list_f, 'M': list_m}
    return result

def main():
    PATH = r'C:\Users\swetlanka\Documents\GitHub\py3\4-1\names\\'
    list_year = [1900,1950,2000]
    print('count_top3({}) =='.format(list_year), top3(list_year, PATH))
    print('count_dynamics({}) =='.format(list_year), dynamics(list_year, PATH))

main()


import psycopg2
import csv
from db.create_connection import create_connection as create_connection

def import_menu_from_csv():
    conn = create_connection()
    cursor = conn.cursor()

    with open("menu.csv", mode="r", encoding="utf-8") as csv_file:
        csv_reader = csv.DictReader(csv_file)
        for row in csv_reader:
            cursor.execute("""
                INSERT INTO menu (name, type, price)
                VALUES (%s, %s, %s)
            """, (row["name"], row["type"], row["price"]))

    conn.commit()
    conn.close()
    cursor.close()

def menu_cleaning():
    try:
        conn = create_connection()
        cursor = conn.cursor()

        cursor.execute("DELETE FROM menu;")
        conn.commit()

        deleted_rows = cursor.rowcount

        return deleted_rows > 0

    except psycopg2.Error as e:
        conn.rollback()
        raise e

    finally:
        if conn is not None:
            conn.close()
            cursor.close()


import numpy as np
import sys
import matplotlib.pyplot as plt

sys.path.append('../../analysis_scripts')

from dumpfile import DumpFile

from pickle_dump import save_obj, load_obj
from spatialcorrelations import calculate_items

if __name__ == "__main__":

    rho = sys.argv[1]

    fps = np.array([0])#,1,5,10,20,40,60,80,100])

    load_prefix = '../raw_data_processing/pickled_data/'

    for fp in fps:

        dc_name = load_prefix + f'ret_o_{fp}_{rho}'

        ret_o = load_obj(dc_name)

        gmatrix = ret_o['sum_g']
        Nsamples = ret_o['g_cnt']

        rs = gmatrix[:,0]/Nsamples

        gs = gmatrix[:,1]/Nsamples

        plt.plot(rs,gs)
        plt.show()


#!/user/bin/env python
# -*- coding:utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import h5py
#一个HDF5文件就是一个容器，用于储存两类对象：datasets，类似于数组的数据集合；groups，类似于文件夹的容器，可以储存datasets和其它groups。
from lr_utils import load_dataset
train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = load_dataset()
# index = 30
# print(train_set_x_orig[index])
# plt.imshow(train_set_x_orig[index])

#打印出当前的训练标签值
#使用np.squeeze的目的是压缩维度，【未压缩】train_set_y[:,index]的值为[1] , 【压缩后】np.squeeze(train_set_y[:,index])的值为1
#print("【使用np.squeeze：" + str(np.squeeze(train_set_y[:,index])) + "，不使用np.squeeze： " + str(train_set_y[:,index]) + "】")
#只有压缩后的值才能进行解码操作
# print("train_set_y=" +str(train_set_y[:,index]))
# print(classes[np.squeeze(train_set_y[:,index])])
# plt.show()
#image.shape[0],image.shape[1],image.shape[2]表示图像长，宽，通道数  image.shape表示图片的维度
m_train=train_set_y.shape[1]
m_test=test_set_y.shape[1]
num_px=train_set_x_orig.shape[1]

print("训练集的数量：m_train="+str(m_train))
print("测试集的数量：m_test="+str(m_test))
print("每张图片的高和宽：num_px="+str(num_px))
print("每张图片的大小：（"+str(num_px)+","+str(num_px)+",3)")
print("训练集图片的维度："+str(train_set_x_orig.shape))
print("训练集标签的维度："+str(train_set_y.shape))
print("测试集图片的维度："+str(test_set_x_orig.shape))
print("测试集标签的维度："+str(test_set_y.shape))
#X_flatten = X.reshape(X.shape [0]，-1).T ＃X.T是X的转置
#将训练集的维度降低并转置。这里的-1被理解为unspecified value，意思是未指定为给定的。如果我只需要特定的行数，列数多少我无所谓，我只需要指定行数，那么列数直接用-1代替就行了，计算机帮我们算赢有多少列，反之亦然。
#如果是reshape(5,-1) 就是将数组变为5行的矩阵，列的话根据具体的来分

train_set_x_flatten  = train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T
#将测试集的维度降低并转置。
test_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T
#
# print ("训练集降维最后的维度： " + str(train_set_x_flatten.shape))
# print ("训练集_标签的维数 : " + str(train_set_y.shape))
# print ("测试集降维之后的维度: " + str(test_set_x_flatten.shape))
# print ("测试集_标签的维数 : " + str(test_set_y.shape))
train_set_x = train_set_x_flatten / 255
test_set_x = test_set_x_flatten / 255

def sigmoid(z):
    """

    :param z: 任意大小的标量或者numpy数组
    :return:
    """
    s=1/(1+np.exp(-z))
    return s

def initialize_with_zero(dim):
    """
    此函数为w创建一个维度为（dim，1）的0向量，并将b初始化为0,w b都被初始化为0
    :param dim:想要的w的大小
    :return:w-维度为（dim,1)的初始化向量  b-初始化的标量
    """
    w=np.zeros(shape=(dim,1))
    b=0
    assert (w.shape==(dim,1))#assert 表示如果出错则终止程序，断言函数是对表达式布尔值的判断，要求表达式计算值必须为真。如果表达式为假，触发异常；如果表达式为真，不执行任何操作。
    assert (isinstance(b,float)or isinstance(b,int))#isinstance() 函数来判断一个对象是否是一个已知的类型，类似 type()。
    return (w,b)

def propagate(w,b,X,Y):
    """

    :param w:权重，大小不等的数组（num_px * num_px * 3，1）
    :param b:偏差，一个标量
    :param X:矩阵类型为（num_px * num_px * 3，训练数量）
    :param Y: 真正的“标签”矢量（如果非猫则为0，如果是猫则为1），矩阵维度为(1,训练数据数量)
    :return:  cost- 逻辑回归的负对数似然成本
        dw  - 相对于w的损失梯度，因此与w相同的形状
        db  - 相对于b的损失梯度，因此与b的形状相同
    """
    m=X.shape[1]  #X=np.array([[1,2,4,5], [3,4,6,1]]),X.shape[0]=2,X.shape[1]=4
    #正向传播
    A=sigmoid(np.dot(w.T,X)+b)
    cost=(-1/m)*(np.sum(Y*np.log(A)+(1-Y)*np.log(1-A)))

    #反向传播
    dw=(1/m)*(np.dot(X,(A-Y).T))
    db=(1/m)*(np.sum(A-Y))
    # 使用断言确保我的数据是正确的
    assert (dw.shape==w.shape)
    assert (db.dtype==float)
    cost=np.squeeze(cost)#只有一行或一列的维度（a singleton dimension）被去除掉了

    assert (cost.shape==())
    grads={
        "dw":dw,
        "db":db
    }
    return (grads,cost)
# #测试一下propagate
# print("====================测试propagate====================")
# #初始化一些参数
# w, b, X, Y = np.array([[1], [2]]), 2, np.array([[1,2], [3,4]]), np.array([[1, 0]])
# grads, cost = propagate(w, b, X, Y)
# print ("dw = " + str(grads["dw"]))
# print ("db = " + str(grads["db"]))
# print ("cost = " + str(cost))
def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost=False):
    """
    此函数通过运行梯度下降算法来优化w和b

    参数：
        w  - 权重，大小不等的数组（num_px * num_px * 3，1）
        b  - 偏差，一个标量
        X  - 维度为（num_px * num_px * 3，训练数据的数量）的数组。
        Y  - 真正的“标签”矢量（如果非猫则为0，如果是猫则为1），矩阵维度为(1,训练数据的数量)
        num_iterations  - 优化循环的迭代次数
        learning_rate  - 梯度下降更新规则的学习率
        print_cost  - 每100步打印一次损失值

    返回：
        params  - 包含权重w和偏差b的字典
        grads  - 包含权重和偏差相对于成本函数的梯度的字典
        成本 - 优化期间计算的所有成本列表，将用于绘制学习曲线。

    提示：
    我们需要写下两个步骤并遍历它们：
        1）计算当前参数的成本和梯度，使用propagate（）。
        2）使用w和b的梯度下降法则更新参数。
    """
    costs = []

    for i in range(num_iterations):
        grads, cost = propagate(w, b, X, Y)

        dw = grads["dw"]
        db = grads["db"]

        w = w - learning_rate * dw
        b = b - learning_rate * db

        # 记录成本
        if i % 100 == 0:
            costs.append(cost)
        # 打印成本数据
        if (print_cost) and (i % 100 == 0):
            print("迭代的次数: %i ， 误差值： %f" % (i, cost))

    params = {
            "w": w,
            "b": b}
    grads = {
            "dw": dw,
            "db": db}
    return (params, grads, costs)

# #测试optimize
# print("====================测试optimize====================")
# w, b, X, Y = np.array([[1], [2]]), 2, np.array([[1,2], [3,4]]), np.array([[1, 0]])
# params , grads , costs = optimize(w , b , X , Y , num_iterations=100 , learning_rate = 0.009 , print_cost = False)
# print ("w = " + str(params["w"]))
# print ("b = " + str(params["b"]))
# print ("dw = " + str(grads["dw"]))
# print ("db = " + str(grads["db"]))

def predict(w, b, X):
    """
        使用学习逻辑回归参数logistic （w，b）预测标签是0还是1，
        参数：
            w  - 权重，大小不等的数组（num_px * num_px * 3，1）
            b  - 偏差，一个标量
            X  - 维度为（num_px * num_px * 3，训练数据的数量）的数据
        返回：
            Y_prediction  - 包含X中所有图片的所有预测【0 | 1】的一个numpy数组（向量）
        """
    m = X.shape[1]  # 图片的数量????为什么是图片的数量
    """
    shape函数是numpy.core.fromnumeric中的函数，它的功能是读取矩阵的长度，
    比如shape[0]就是读取矩阵第一维度的长度。
    shape的输入参数可以是一个整数（表示维度），也可以是一个矩阵。
    """
    Y_prediction = np.zeros((1, m))
    w = w.reshape(X.shape[0], 1)  # reshape函数：改变数组的维数

    # 计预测猫在图片中出现的概率
    A = sigmoid(np.dot(w.T, X) + b)
    for i in range(A.shape[1]):
        # 将概率a[0,i]转换为实际预测p[0,i]
        Y_prediction[0, i] = 1 if A[0, i] > 0.5 else 0
        # 使用断言
    assert (Y_prediction.shape == (1, m))
    return Y_prediction

#
# #测试predict
# print("------测试predict------")
# w,b,X,Y = np.array([[1],[2]]),2,np.array([[1,2],[3,4]]),np.array([[1,0]])
# print("predictions = " + str(predict(w,b,X)))
def model(X_train, Y_train, X_test, Y_test, num_iterations=2000, learning_rate=0.5, print_cost=False):
    """
    通过调用之前实现的函数来构建逻辑回归模型
    参数：
        X_train  - numpy的数组,维度为（num_px * num_px * 3，m_train）的训练集
        Y_train  - numpy的数组,维度为（1，m_train）（矢量）的训练标签集
        X_test   - numpy的数组,维度为（num_px * num_px * 3，m_test）的测试集
        Y_test   - numpy的数组,维度为（1，m_test）的（向量）的测试标签集
        num_iterations  - 表示用于优化参数的迭代次数的超参数
        learning_rate  - 表示optimize（）更新规则中使用的学习速率的超参数
        print_cost  - 设置为true以每100次迭代打印成本
    返回：
        d  - 包含有关模型信息的字典。
    """
    w, b = initialize_with_zero(X_train.shape[0])
    parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)

    # 从字典“参数”中检索参数w和b
    w, b = parameters["w"], parameters["b"]

    # 预测测试/训练集的例子
    Y_prediction_test = predict(w, b, X_test)
    Y_prediction_train = predict(w, b, X_train)

    # 打印训练后的准确性
    print("训练集准确性：", format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100), "%")  # mean()函数功能：求取均值,np.abs()返回决定值
    print("测试集准确性：", format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100), "%")  # abs() 函数返回数字的绝对值

    d = {
        "costs": costs,
        "Y_prediction_test": Y_prediction_test,
        "Y_prediction_train": Y_prediction_train,
        "w": w,
        "b": b,
        "learning_rate": learning_rate,
        "num_iterations": num_iterations}
    return d

print("------测试model------")
# 这里加载的是真实的数据，请参见上面的代码部分
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations=2000, learning_rate=0.005, print_cost=True)

# 绘制图
costs = np.squeeze(d['costs'])
"""
squeeze（）函数的用法:
在机器学习和深度学习中，通常算法的结果是可以表示向量的数组（即包含两对或以上的方括号形式[[]]），
如果直接利用这个数组进行画图可能显示界面为空（见后面的示例）。我们可以利用squeeze（）函数将表示向量
的数组转换为秩为1的数组，这样利用matplotlib库函数画图时，就可以正常的显示结果了。
"""
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations(per hundreds)')
plt.title("Learning rate = " + str(d["learning_rate"]))
plt.show()

learning_rates = [0.01, 0.001, 0.0001]
models = {}
for i in learning_rates:
    print("learning rate is:" + str(i))
    models[str(i)] = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations=1500, learning_rate=i,
                           print_cost=False)
    print('\n' + "--------------" + '\n')

for i in learning_rates:
    plt.plot(np.squeeze(models[str(i)]["costs"]), label=str(models[str(i)]["learning_rate"]))

plt.ylabel('cost')
plt.xlabel('iterations')

legend = plt.legend(loc='upper center', shadow=True)  # loc:图例所有figure位置;shadow:控制是否在图例后面画一个阴影
# 设置图例legend背景颜色
frame = legend.get_frame()
frame.set_facecolor('0.90')
plt.show()


"""
Author: Walfred Cutaran

Problem: Given a time in -hour AM/PM format, convert it to military (24-hour) time.

Note: - 12:00:00AM on a 12-hour clock is 00:00:00 on a 24-hour clock.
- 12:00:00PM on a 12-hour clock is 12:00:00 on a 24-hour clock.

"""

#
# Complete the 'timeConversion' function below.
#
# The function is expected to return a STRING.
# The function accepts STRING s as parameter.
#

def timeConversion(s):
    ans = ""
    s_end = s[8:] # am or pm
    s = s[:8]
    s = s.split(':')

    if s_end == "AM":
        if s[0] == "12":
            ans += "00:"
        else:
            ans += s[0] + ':'

        ans += s[1] + ':'
        ans += s[2]
        return ans

    # if end == pm

    if s[0] == "12":
        ans += s[0] + ':'
        ans += s[1] + ':'
        ans += s[2]
        return ans

    else:
        ans += str(int(s[0]) + 12) + ':'
        ans += s[1] + ':'
        ans += s[2]
        return ans


import random

print("Input 2 numbers and guess the random number the computer chose")

def guess_game():
    # Lets the user choose lower limit, higher limit and number of tries
    try:
        first_num = int(input("Input the lower limit number: "))
        second_num = int(input("Input the higher limit number: "))
        number_of_chance = int(input("Input the number of tries: "))
    except:
        print("Input only numbers!")
        guess_game()

    # Filter out input that doesn't make sense
    if first_num > second_num:
        print("Lower limit number must be lower than Higher limit number")
        guess_game()
    elif number_of_chance == 0:
        print("Number of chance must be more than 0")
        guess_game()
    else:
        print(f"The computer is going to randomly select a number between {first_num} and {second_num}")
        print(f"You have {number_of_chance} tries")
        global guess_num
        guess_num = random.randint(first_num, second_num)
        print(guess_num)
        for x in range(1, number_of_chance + 1, 1):
            user_guess = int(input(f"Guess {x} : "))
            if user_guess == guess_num:
                print(f"Congrats! The number is {guess_num}")
                break
            elif user_guess < guess_num:
                print("The number is higher")
            elif user_guess > guess_num:
                print("The number is lower")
        print("Game has ended")
        # Whether user wants to continue
        user_play = input("Type 'C' to continue or any other keys to quit: ").capitalize()
        if user_play == 'C':
            guess_game()
        else:
            quit()

# Start the game
guess_game()


import os
import csv

#Create file path variable
budget_csv = os.path.join("Resources", "budget_data.csv")

#Create empty lists to store data as we iterate through the CSV file.
date = []
profitLoss = []
monthlyChange = []

#Open CSV file and create reader.
with open(budget_csv, encoding='utf8', newline='') as csvfile:
    csvreader = csv.reader(csvfile, delimiter=',')

    #Skip the header row.
    csv_header = next(csvreader)

    #Iterate through CSV file and record Date and Profit/Loss data in
    #each appropriate list
    for row in csvreader:
        date.append(row[0])
        profitLoss.append(row[1])

#cast list as integer using list comprehension.
ProfitLossInt = [int(i) for i in profitLoss]

#sum of profit and loss.
Total = sum(ProfitLossInt)

#Iterate through Profit/Loss rows tofind monthly change and put it in a list.
#It needs to  be off set by 1 because
#otherwise it will iterate beyond the last row since using i+1 in conditional statement.
for i in range(len(ProfitLossInt)-1):
    if i+1 <= len(ProfitLossInt):
        monthlyChange.append(ProfitLossInt[i+1] - ProfitLossInt[i])

#Create an function to calculate average.
def average(mylist):
    return sum(mylist)/len(mylist)

monthlyChangeAvg = round(average(monthlyChange),2)

#Find the maximum and minimum monthly change.
monthlyChangeMax = max(monthlyChange)
monthlyChangeMin = min(monthlyChange)

#find the date that corresponds to the maxium and minimum monthly change
MaxDate = date[monthlyChange.index(max(monthlyChange))+1]
MinDate = date[monthlyChange.index(min(monthlyChange))+1]

#Print output to console and create text file summary
print("Financial Analysis")
print("-------------------------------")
print("Total Months: " + str(len(date)))
print(f"Total: ${Total}")
print(f"Average Change: ${monthlyChangeAvg}")
print(f"Greatest Increase in Profits: {MaxDate} (${monthlyChangeMax})")
print(f"Greatest Decrease in Profits: {MinDate} (${monthlyChangeMin})")

output = open("Financial_Analysis.txt", "w")
output.write("Financial Analysis\n")
output.write("-------------------------------\n")
output.write("Total Months: " + str(len(date))+"\n")
output.write(f"Total: ${Total}\n")
output.write(f"Average Change: ${monthlyChangeAvg}\n")
output.write(f"Greatest Increase in Profits: {MaxDate} (${monthlyChangeMax})\n")
output.write(f"Greatest Decrease in Profits: {MinDate} (${monthlyChangeMin})\n")
output.close()

os.startfile("Financial_Analysis.txt")


# [https://www.yahoo.com/somerandomstring, http://www.yahoo.com/some/random/string, http://www.google.com]
import re

def condense(arr):
    d = {}
    output = []
    domain = re.compile(r'www.\w*.\w*')
    cleanarr = domain.findall(''.join(arr))
    for i in cleanarr:
        if i in d:
            d[i] += 1
        else:
            d[i] = 1

    for k,v in d.items():
        output.append(k+' '+str(v))
    return output
print(condense(["https://www.yahoo.com/somerandomstring", "http://www.yahoo.com/some/random/string", "http://www.google.com"]))


def sequential_search(data, key):
    for item in data:
        if item == key:
            return True
    return False

my_list = [3, 6, 2, 9, 4, 7]
key = 6
found = sequential_search(my_list, key)
if found:
    print("elemen ditemukan.")
else:
    print("elemen tidak ditemukan")


import sys
input = sys.stdin.readline

input_num = int(input())
ops = [0 for _ in range(input_num+1)]

for i in range(2, input_num+1):
    ops[i] = ops[i-1]+1
    if i % 3 == 0:
        ops[i] = min(ops[i], ops[i//3] + 1)
    if i % 2 == 0:
        ops[i] = min(ops[i], ops[i//2] + 1)

print(ops[input_num])


import os
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.gridspec as gridspec

def plot(samples):

    x_dim=samples.shape[1]
    color=samples.shape[3]
    fig = plt.figure(figsize=(4, 4))
    gs = gridspec.GridSpec(4, 4)
    gs.update(wspace=0.05, hspace=0.05)

    for i, sample in enumerate(samples):
        ax = plt.subplot(gs[i])
        plt.axis('off')
        ax.set_xticklabels([])
        ax.set_yticklabels([])
        ax.set_aspect('equal')
        if samples.shape[3] == 3:
            sample = sample.reshape(x_dim, x_dim, color)
            plt.imshow(sample)
        else:
            sample = sample.reshape(x_dim, x_dim)
            plt.imshow(sample, cmap='Greys_r')

    return fig

def generateSamples(out_dir, z_dim=100):
#     fileNames=[]
    if not os.path.exists(out_dir+'/generated/'):
            os.makedirs(out_dir+'/generated/')

    for root, dirs, files in os.walk(out_dir+"/model/"):
        for filename in sorted(files):
            if os.path.splitext(filename)[1].lower() =='.meta':
                model=root+os.path.splitext(filename)[0]
                imageName=os.path.splitext(filename)[0]
                print(model)
#                 fileNames.append(root+os.path.splitext(filename)[0])

                tf.reset_default_graph()
                with tf.Session() as sess:
                #     z = tf.placeholder(tf.float32, shape=[None, z_dim])
                #     saver = tf.train.Saver()
                    saver=tf.train.import_meta_graph(model+'.meta')
                    saver.restore(sess, model)
                    graph=tf.get_default_graph()

                    tName1=graph.get_operation_by_name('z').name+':0'
                    z=graph.get_tensor_by_name(tName1)

                    tName2=graph.get_operation_by_name('generator/final_gen').name+':0'
                    gen=graph.get_tensor_by_name(tName2)

                    np.random.seed(42)

                    batch_z = np.random.normal(-1.0, 1.0, size=[16, z_dim]).astype(np.float32)

                    samples = sess.run(gen, feed_dict={z: batch_z})

                    fig = plot(samples)

                    plt.savefig(out_dir+'/generated/{}.png'
                                .format(imageName), bbox_inches='tight')

                    plt.show()
                    plt.close()


import enum

from PySide2 import QtCore
from PySide2.QtCore import QPoint
from PySide2.QtGui import QColor, QFont, QFontDatabase
from PySide2.QtWidgets import QGraphicsSceneMouseEvent, QGraphicsItem

class NodeState(enum.Enum):
    normal = 0
    used = 1
    highlight = 2

class Node(QGraphicsItem):
    Type = QGraphicsItem.UserType + 1

    def __init__(self, graphWidget, name: str, group_name: str, size=22):
        QGraphicsItem.__init__(self)
        self.state = NodeState.normal
        self.size = size

        self.fixedFont = QFont("Monospace")
        self.fixedFont.setStyleHint(QFont.TypeWriter)
        self.group_name = group_name
        self.name = name
        self.tag = group_name + " " + self.name
        self.color = QColor('light green')

        # self.setFlag(QGraphicsItem.ItemIsMovable)
        # self.setFlag(QGraphicsItem.ItemIsSelectable)
        self.setCacheMode(self.DeviceCoordinateCache)
        self.setZValue(-1)

    def mousePressEvent(self, event: QGraphicsSceneMouseEvent):
        # self.state=NodeState.highlight
        print(self.state)
        # self.color = QColor('cyan')
    #     self.adjust()
    #     self.update()
    #
    # def adjust(self):
    #     if self.state != NodeState.highlight:
    #         print("sd")
    #     if self.state == NodeState.normal:
    #         self.color = QColor('light green')
    #     elif self.state == NodeState.used:
    #         self.color = QColor('yellow')
    #     elif self.state == NodeState.highlight:
    #         self.color = QColor('cyan')
    #         print(("Ss"))

    def type(self):
        return Node.Type

    def boundingRect(self):
        return QtCore.QRectF((self.size // 2) * -1, (self.size // 2) * -1, self.size, self.size)

    def paint(self, painter, option, widget):
        if self.state == NodeState.normal:
            self.color = QColor('light green')
        elif self.state == NodeState.used:
            self.color = QColor('yellow')
        elif self.state == NodeState.highlight:
            self.color = QColor('cyan')
        painter.setPen(QColor("black"))
        painter.setBrush(self.color)
        painter.drawRect((self.size // 2) * -1, (self.size // 2) * -1, self.size, self.size)

        painter.setPen(QColor("black"))
        painter.setFont(self.fixedFont)

        if len(self.name) >= 3:
            textpoint = QPoint(-11, 3)
        elif len(self.name) >= 2:
            textpoint = QPoint(-7, 3)
        else:
            textpoint = QPoint(-4, 3)
        painter.drawText(textpoint, self.name)


import pytest

from pysyncgateway import Database, Query

@pytest.fixture
def database(admin_client):
    """
    Returns:
        Database: 'db' database written to Sync Gateway.
    """
    database = Database(admin_client, 'db')
    database.create()
    return database

@pytest.fixture
def query(database):
    """
    Returns:
        Query: Not written to Sync Gateway.
    """
    return Query(database, 'all_lists')

@pytest.fixture
def slow_view(database):
    """
    A view that returns all documents, but slowly. This uses a horrible
    sleep-like function that locks up Walrus for 1.5s per document. Fixture
    populates the database with a document to ensure that calling the
    view takes at least 1 second in total.

    NOTE: On Circle, it looks like processing the view might be done in
    parallel because it is able to return a view containing 2 documents in just
    over the time in the delay function.

    Returns:
        Query: Called 'slow_lists', written to Sync Gateway, with a single view
            called 'all' that takes 1.5 second per document in the database.
    """
    database.get_document('a').create_update()
    query = Query(database, 'slow_lists')
    query.data = {
        'views': {
            'all': {
                'map':
                """
function(doc, meta) {
    function pausecomp(millis){
        var date = new Date();
        var curDate = null;
        do { curDate = new Date(); }
        while(curDate-date < millis);
    }
    pausecomp(1500);
    emit(meta.id,doc);
}
        """,
            },
        },
    }
    query.create_update()
    return query

@pytest.fixture
def food_query(database):
    """
    Populates the database with some foods and builds a query, all written to
    Sync Gateway. View does not need hotting up because docs are in place when
    it is created.

    Returns:
        Query: With 'all' view populated where key will search for the foods
            where the first letter of the name of the food matches.
    """
    for name, data in [
        ('lightbulb', {
            'type': 'fixture',
            'name': 'Lightbulb',
        }),
        ('apple', {
            'type': 'food',
            'name': 'apple',
        }),
        ('banana', {
            'type': 'food',
            'name': 'banana',
        }),
        ('apricot', {
            'type': 'food',
            'name': 'apricot',
        }),
        ('walrus', {
            'type': 'animal',
            'name': 'I AM THE WALRUS',
        }),
        ('almond', {
            'type': 'food',
            'name': 'almond',
        }),
        ('pumpkin', {
            'type': 'food',
            'name': 'pumpkin',
        }),
    ]:
        doc = database.get_document(name)
        doc.data = data
        doc.create_update()
    query = Query(database, 'food_index')
    query.data = {
        'views': {
            'all': {
                'map':
                """
function(doc, meta) {
    if(doc.type == "food" && doc.name) {
        emit(doc.name[0], doc)
    }
}
""",
            },
        },
    }
    query.create_update()
    return query


def solution(n):
    answer = []
    triangle = [[0] * n for _ in range(n)]
    num = 1
    x, y = -1, 0

    for i in range(n):
        for j in range(i, n):
            if i % 3 == 0:
                x += 1
            elif i % 3 == 1:
                y += 1
            elif i % 3 == 2:
                x -= 1
                y -= 1
            triangle[x][y] = num
            num += 1
    for tri in triangle:
        for t in tri:
            if t != 0:
                answer.append(t)
    return answer

if __name__ == '__main__':
    real_answer = solution(4)
    print('정답 : ', real_answer)


# ##### BEGIN GPL LICENSE BLOCK #####
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software Foundation,
#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####

import bpy
from bpy.types import Header, Menu, Panel, PropertyGroup

from fd_datablocks import enums, const

import os

from bpy.props import (StringProperty,
                       BoolProperty,
                       IntProperty,
                       FloatProperty,
                       FloatVectorProperty,
                       BoolVectorProperty,
                       PointerProperty,
                       CollectionProperty,
                       EnumProperty)

def find_node(material, nodetype):
    if material and material.node_tree:
        ntree = material.node_tree

        for node in ntree.nodes:
            if getattr(node, "type", None) == nodetype:
                return node

    return None

def find_node_input(node, name):
    for input in node.inputs:
        if input.name == name:
            return input

    return None

def panel_node_draw(layout, id_data, output_type, input_name):
    if not id_data.use_nodes:
        layout.operator("cycles.use_shading_nodes", icon='NODETREE')
        return False

    ntree = id_data.node_tree

    node = find_node(id_data, output_type)
    if not node:
        layout.label(text="No output node")
    else:
        input = find_node_input(node, input_name)
        layout.template_node_view(ntree, node, input)

    return True

class PANEL_scenes(Panel):
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Scenes"
    bl_context = "objectmode"
    bl_label = " "
    bl_options = {'HIDE_HEADER'}
    #bl_idname = "mvProject.part_properties"

    def draw_header(self,context):
        layout = self.layout
        row = layout.row(align=True)
        row.label("Scenes:        ",icon='SCENE_DATA')

    @classmethod
    def poll(cls, context):
        return True

    def draw(self, context):
        unit = context.scene.unit_settings
        scene = context.scene
        layout = self.layout
        space = context.space_data

        col = layout.column(align=True)
        box = col.box()
        row = box.row(align=True)
        row.template_ID(context.screen, "scene", new="fd_scene.create_scene", unlink="scene.delete")
        box = col.box()
        row = box.row()
        row.prop(scene, "camera",text="Active Camera")
        row = box.row()
        row.label("Main Units:")
        row.row().prop(unit, "system", expand=True)
        row = box.row()
        row.label("Angle Units:")
        row.row().prop(unit, "system_rotation", expand=True)
        if space.type == 'VIEW_3D' and scene.unit_settings.system == 'NONE':
            row = box.row()
            row.label("Grid Spacing:")
            row.row().prop(space, "grid_scale", expand=True)
        box = col.box()
        scene.mv.PromptPage.draw_prompt_page(box,scene)

class PANEL_worlds(Panel):
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Worlds"
    bl_context = "objectmode"
    bl_label = " "
    bl_options = {'HIDE_HEADER'}
    #bl_idname = "mvProject.part_properties"

    def draw_header(self,context):
        layout = self.layout
        row = layout.row(align=True)
        row.label("World Management:        ",icon=const.icon_world)

    @classmethod
    def poll(cls, context):
        return True

    def draw(self, context):
        scene = context.scene
        world = context.scene.world
        layout = self.layout
        col = layout.column(align=True)
        box = col.box()
        row = box.row(align=True)
        row.template_ID(context.scene, "world", new="world.new")
        box = col.box()
        if not panel_node_draw(box, world, 'OUTPUT_WORLD', 'Surface'):
            box.prop(world, "horizon_color", text="Color")
        box = col.box()
        world.mv.PromptPage.draw_prompt_page(box,world)

class PANEL_materials(Panel):
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Materials"
    bl_context = "objectmode"
    bl_label = " "
    bl_options = {'HIDE_HEADER'}

    def draw_header(self,context):
        layout = self.layout
        row = layout.row(align=True)
        row.label("Material Management:        ",icon=const.icon_material)

    @classmethod
    def poll(cls, context):
        return True

    def draw(self, context):
        layout = self.layout
        box = layout.box()
        row = box.row()
        row.operator("fd_material.apply_materials_from_pointers",text="Assign Materials",icon=const.icon_material)
        row.operator("fd_material.clear_unused_materials_from_file",text="Clear Unused",icon='ZOOMOUT')
        row.operator("fd_material.clear_all_materials_from_file",text="Clear All",icon='PANEL_CLOSE')
        box.template_list("MATERIAL_UL_matslots", "", bpy.data, "materials", context.scene.mv, "active_material_index", rows=5)
        if len(bpy.data.materials) > 0:
            box = layout.box()
            material = bpy.data.materials[context.scene.mv.active_material_index]
            material.mv.draw_properties(box,material)

class PANEL_libraries(Panel):
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_category = "Libraries"
    bl_context = "objectmode"
    bl_label = " "
    bl_options = {'HIDE_HEADER'}

    def draw_header(self,context):
        layout = self.layout
        row = layout.row(align=True)
        row.label("Library Management:        ",icon=const.icon_library)

    @classmethod
    def poll(cls, context):
        return True

    def draw(self, context):
        dm = context.scene.mv.dm
        layout = self.layout
        col = layout.column(align=True)
        box = col.box()
        if os.path.exists(dm.Libraries.path):
            Libraries = context.scene.mv.dm.Libraries
            row = box.row(align=True)
            row.prop(dm.Libraries,"path",text="",icon='FILE_TICK')
#             box = col.box()
#             row = box.row(align=True)
#             Libraries.draw_active_pointer_library_menus(row)
        else:
            row = box.row(align=True)
            row.prop(dm.Libraries,"path",text="",icon='ERROR')
        dm.Specgroups.draw_spec_groups(box)

#------REGISTER
classes = [
           PANEL_scenes,
           PANEL_worlds,
           PANEL_materials,
           PANEL_libraries
           ]

def register():
    for c in classes:
        bpy.utils.register_class(c)

def unregister():
    for c in classes:
        bpy.utils.unregister_class(c)

if __name__ == "__main__":
    register()


"""
@Author : Hirsi
@ Time :  2020/7/3
"""

"""
思路(线程池)
    1.定义变量，保存源文件夹，目标文件夹所在的路径
    2.在目标路径创建新的文件夹
    3.获取源文件夹中所有的文件(列表)
    4.便利列表，得到所有的文件名
    5.定义函数，进行文件拷贝
    文件拷贝函数 参数(源文件夹路径，目标文件夹路径，文件名)
        1.拼接源文件和目标文件的具体路径
        2.打开源文件，创建目标文件
        3.读取源文件的内容，写入到目标文件中(while)
"""
import os
import multiprocessing
import time

# 5.定义函数，进行文件拷贝
def copy_work(source_dir,dest_dir,file_name):
    print(multiprocessing.current_process().name)
    # 1.拼接源文件和目标文件的具体路径,打开源文件，创建目标文件
    source_path=source_dir+'/'+file_name
    dest_path=dest_dir+'/'+file_name
    # 3.读取源文件的内容，写入到目标文件中(while)
    with open(source_path,'rb') as source_file:
        with open(dest_path,'wb') as dest_file:
            while True:
                read_data = source_file.read(1024)
                if read_data:
                    dest_file.write(read_data)
                    time.sleep(0.5)
                else:
                    break

if __name__ == '__main__':
    # 1.定义变量，保存源文件夹，目标文件夹所在的路径
    source_dir='./test'
    dest_dir='/home/hirsi/桌面/test'
    # 2.在目标路径创建新的文件夹
    try:
        os.mkdir(dest_dir)
    except:
        print('文件已存在!')
    # 3.获取源文件夹中所有的文件(列表)
    file_list = os.listdir(source_dir)

    # ***创建进程池
    pool = multiprocessing.Pool(3)

    # 4.遍历列表，得到所有的文件名
    for file_name in file_list:
        # 单进程
        # copy_work(source_dir,dest_dir,file_name)
        pool.apply_async(copy_work,(source_dir,dest_dir,file_name))

    # 不再接受新的任务
    pool.close()
    # 让主进程等待进程池结束后再退出
    pool.join()
    print('复制完成!')

day07-多任务-进程/10-文件夹拷贝器_多进程版.py

10-文件夹拷贝器_多进程版.py


from selenium.webdriver import Chrome,ChromeOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import xlsxwriter

opts = ChromeOptions()
opts.add_experimental_option("detach", True)
driver = Chrome(chrome_options=opts)

driver.get("https://google.com")
driver.maximize_window()

searchBox = driver.find_element(By.CLASS_NAME,"gLFyf")

searchBox.send_keys("IBTECH")
searchBox.send_keys(Keys.ENTER)

def purifyExtensions(i, j):
    if '.net' in newLinks[i][j]:
        newRefs.append(newLinks[i][j].split('.net'))
    elif '.io' in newLinks[i][j]:
        newRefs.append(newLinks[i][j].split('.io'))
    elif '.gov' in newLinks[i][j]:
        newRefs.append(newLinks[i][j].split('.gov'))
    elif '.org' in newLinks[i][j]:
        newRefs.append(newLinks[i][j].split('.org'))
    elif '.dev' in newLinks[i][j]:
        newRefs.append(newLinks[i][j].split('.dev'))
    else:
        newRefs.append(newLinks[i][j].split('.com'))

newLinks = []
newRefs = []

for i in range(3):
    links = driver.find_elements(By.CLASS_NAME,"yuRUbf")
    driver.implicitly_wait(3)
    for k in range(1):
        for j in range(9):
            newLinks.append(links[j].text.split('https://'))
    if i == 0:
        for j in range(1):
            for k in range(9):
                purifyExtensions(k,1)
                #newRefs.append(newLinks[k][1].split('.com'))
        driver.find_element(By.XPATH, '//*[@id="pnnext"]/span[2]').click()
    elif i == 1:
        for j in range(1):
            for k in range(9):
                if k ==4:
                    purifyExtensions(k+9,0)
                    #newRefs.append(newLinks[k + 9][0].split('.com'))
                else:
                    purifyExtensions(k + 9, 1)
                    #newRefs.append(newLinks[k + 9][1].split('.com'))
        driver.find_element(By.XPATH, '//*[@id="pnnext"]/span[2]').click()
    elif i == 2:
        for j in range(1):
            for k in range(9):
                purifyExtensions(k+18,1)
                #newRefs.append(newLinks[k+18][1].split('.com'))

driver.close()

workbook = xlsxwriter.Workbook('import_file.xlsx')
worksheet = workbook.add_worksheet()

worksheet.set_column('A:A', len(newLinks))
worksheet.set_column('B:B', len(newLinks))

text1 = 'A{n:.2f}'
text2 = 'B{n:.2f}'
for j in range(len(newLinks)):
    for k in range(1):
        stringLink = newLinks[j][k]
        stringRef = newRefs[j][k]
        worksheet.write(text1.format(n = j+1), stringLink)
        worksheet.write(text2.format(n = j+1), 'https://' + stringRef + '.com')

workbook.close()


import os

from .register import register_cityscapes_segmentation, register_voc_context_segmentation_dataset
from .seg_builtin_meta import get_segmentation_builtin_meta_data

_CITYSCAPES_SPLITS = {}
_CITYSCAPES_SPLITS['cityscapes'] = {
    'cityscapes_train': ('cityscapes/leftImg8bit/train', 'cityscapes/gtFine/train'),
    'cityscapes_val': ('cityscapes/leftImg8bit/val', 'cityscapes/gtFine/val'),
    'cityscapes_test': ('cityscapes/leftImg8bit/test', 'cityscapes/gtFine/test')
}

def register_cityscapes(root):
    for dataset_name, splits_per_dataset in _CITYSCAPES_SPLITS.items():
        for k, (image_root, label_root) in splits_per_dataset.items():
            meta_data = get_segmentation_builtin_meta_data(dataset_name)
            # Registe Dataset
            register_cityscapes_segmentation(k, meta_data, os.path.join(root, image_root), os.path.join(root, label_root))

_RAW_VOC_CONTEXT_SPLITS = {}
_RAW_VOC_CONTEXT_SPLITS['voc_context'] = {
    "voc_context_seg_train": ("Context/train", "Context/train_labels"),
    "voc_context_seg_val": ("Context/val", "Context/val_labels"),
}

def register_voc_context(root):
    for dataset_name, splits_per_dataset in _RAW_VOC_CONTEXT_SPLITS.items():
        for k, (image_root, label_root) in splits_per_dataset.items():
            metadata = get_segmentation_builtin_meta_data(dataset_name)
            # Registe Dataset

            register_voc_context_segmentation_dataset(k, metadata, os.path.join(root, image_root), os.path.join(root, label_root))


import numpy as np
import pandas as pd

def main():
    df1 = pd.DataFrame()
    print(df1)
    time_vals = np.arange(1628610738, 1628611738)
    data_vals = np.ones(1000)
    s1 = pd.Series(data_vals, time_vals)
    df1['S1'] = s1
    print(df1)
    dv2 = np.random.uniform(10, 20, 1000)
    s2 = pd.Series(dv2, time_vals)
    df1['S2'] = s2
    df1.to_csv('df1.csv', index_label='timestamp')
    print(df1)
    tv2 = np.arange(1628611738, 1628611838)
    s3 = pd.Series(np.ones(100)*2, tv2)
    df2 = pd.DataFrame({'S1': s3, 'S2': pd.Series(np.array(np.random.poisson(10, 100), dtype=float), tv2)})
    print(df2)
    df3 = df1.merge(df2, 'outer')
    print(df3)
    df4 = pd.DataFrame({'S1': data_vals, 'S2': dv2}, time_vals)
    print(df4)

if __name__ == '__main__':
    main()


import gradio as gr
import pytesseract
from langchain import PromptTemplate
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from pdf2image import convert_from_path

# 質問テンプレート
template = """
あなたは親切なアシスタントです。下記の質問に日本語で回答してください。
質問：{question}
回答：
"""

prompt = PromptTemplate(
    input_variables=["question"],
    template=template,
)

def pdf_to_text_ocr(pdf_file):
    images = convert_from_path(pdf_file)
    text = ""

    for image in images:
        text += pytesseract.image_to_string(image, lang="jpn+eng")

    return text

def process_input(pdf_file, input_text):
    # PDFファイルの読み込み
    pdf_text = pdf_to_text_ocr(pdf_file.name)

    # テキストの分割
    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
    texts = text_splitter.create_documents([pdf_text])

    # 埋め込みの作成
    embeddings = OpenAIEmbeddings()
    vectordb = Chroma.from_documents(texts, embeddings)

    # RetrievalQAの作成
    qa = RetrievalQA.from_chain_type(llm=ChatOpenAI(model_name="gpt-3.5-turbo"), chain_type="stuff",
                                     retriever=vectordb.as_retriever())

    # 質問の送信と回答の取得
    question = input_text
    query = prompt.format(question=question)
    response = qa.run(query)

    return response

# UIコンポーネントの作成
pdf_upload = gr.inputs.File(type="file", label="PDFファイルをアップロード")
textarea = gr.inputs.Textbox(lines=15, placeholder="GPTの応答がここに表示されます...", label="GPT")
input_box = gr.inputs.Textbox(lines=1, placeholder="ここに質問を入力してください", label="")

iface = gr.Interface(
    fn=process_input,
    inputs=[pdf_upload, input_box],
    outputs=textarea,
    layout="vertical",
    css=".gr-input {width: 80%;}",
    allow_flagging='never'
)

iface.launch()


import os
from unittest import TestCase

import jinja2

from apply.issue.issure_js_auto_code.db_util import res_to_dict
from config.db_conf import localhost_oa_engine
from util.str_util import to_lower_camel, to_snake, to_upper_camel

class Form:

    @staticmethod
    def get_tables(db):
        sql = "select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = %(db)s"
        res = localhost_oa_engine.execute(sql, {"db": db})
        return res_to_dict(res)

    @staticmethod
    def get_table_info(table_name, db=None):
        # 表名,表注释
        # 字段名,字段类型,字段注释, 枚举值

        # json数据 -- class数据-- 类数据
        sql = """SELECT COL.COLUMN_NAME, COL.COLUMN_TYPE, COL.COLUMN_COMMENT, COL.DATA_TYPE
        FROM INFORMATION_SCHEMA.COLUMNS COL
        Where COL.table_schema = %(db)s AND COL.TABLE_NAME = %(table_name)s"""

        args = {"db": db, "table_name": table_name}
        res = localhost_oa_engine.execute(sql, args)
        data = res_to_dict(res)
        for item in data:
            item["COLUMN_NAME"] = to_lower_camel(item["COLUMN_NAME"])
        return data

    @staticmethod
    def to_file(data_dic, path, resource_dir, template_file):
        template_loader = jinja2.FileSystemLoader(searchpath=resource_dir)
        template_env = jinja2.Environment(loader=template_loader)
        template = template_env.get_template(template_file)
        output_text = template.render(data_dic)
        with open(path, "w", encoding="utf-8") as f:
            f.write(output_text)

class TestAutoCode(TestCase):

    def test_run(self):
        table = "organization"
        rows = Form.get_table_info(table, "oa")
        data = {
            "list": rows
        }
        Form.to_file(data, f"{table}.vue", os.path.dirname(__file__), "templates/vue.template")

    def test_run_vue_js(self):
        tables = Form.get_tables("oa")
        for table in tables:
            table_name = table["TABLE_NAME"]
            table_upper_caml = to_upper_camel(table_name)
            rows = Form.get_table_info(table_name, "oa")
            data = {
                "list": rows,
                "tableUpperCaml": table_upper_caml,
                "tableConst": to_snake(table_name).upper(),
            }
            Form.to_file(data, f"tmp/{table_upper_caml}.vue", os.path.dirname(__file__), "templates/vue.template")

    def test_run_index_js(self):
        tables = Form.get_tables("oa")
        table_infos = []
        for table in tables:
            table_name = table["TABLE_NAME"]
            table_upper_caml = to_upper_camel(table_name)
            table_infos.append({
                "tableUpperCaml": table_upper_caml,
                "tableLowerCaml": to_lower_camel(table_name),
                "tableConst": to_snake(table_name).upper(),
            })
        data = {
            "list": table_infos
        }
        Form.to_file(data, "tmp/routes.js", os.path.dirname(__file__), "templates/routes.template")

    def test_run_config_js(self):
        tables = Form.get_tables("oa")
        table_infos = []
        for table in tables:
            table_name = table["TABLE_NAME"]
            table_infos.append({
                "tableLowerCaml": to_lower_camel(table_name),
                "tableConst": to_snake(table_name).upper(),
            })
        data = {
            "list": table_infos
        }
        Form.to_file(data, "tmp/config.js", os.path.dirname(__file__), "templates/config.template")


#!/usr/bin/python3
"""
The function "add_integer" adds two integers
"""

def add_integer(a, b=98):
    """
    Check if arguments are of the required type, else raise TypeError
    """
    if a is None and b is None:
        raise TypeError("add_integer() missing 1 required"
                        "positional argument: 'a'")
    if not isinstance(a, (int, float)):
        raise TypeError("a must be an integer")
    if not isinstance(b, (int, float)):
        raise TypeError("b must be an integer")
    if a + 1 == a:
        raise OverflowError("a too large")
    if b + 1 == b:
        raise OverflowError("b too large")
    """
    Convert arguments to int if they are float and return the sum
    """
    return int(a) + int(b)


try:
	from zohocrmsdk.src.com.zoho.crm.api.exception import SDKException
	from zohocrmsdk.src.com.zoho.crm.api.util import Constants
except Exception:
	from ..exception import SDKException
	from ..util import Constants

class Backup(object):
	def __init__(self):
		"""Creates an instance of Backup"""

		self.__rrule = None
		self.__id = None
		self.__start_date = None
		self.__scheduled_date = None
		self.__status = None
		self.__requester = None
		self.__key_modified = dict()

	def get_rrule(self):
		"""
		The method to get the rrule

		Returns:
			string: A string representing the rrule
		"""

		return self.__rrule

	def set_rrule(self, rrule):
		"""
		The method to set the value to rrule

		Parameters:
			rrule (string) : A string representing the rrule
		"""

		if rrule is not None and not isinstance(rrule, str):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: rrule EXPECTED TYPE: str', None, None)

		self.__rrule = rrule
		self.__key_modified['rrule'] = 1

	def get_id(self):
		"""
		The method to get the id

		Returns:
			int: An int representing the id
		"""

		return self.__id

	def set_id(self, id):
		"""
		The method to set the value to id

		Parameters:
			id (int) : An int representing the id
		"""

		if id is not None and not isinstance(id, int):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: id EXPECTED TYPE: int', None, None)

		self.__id = id
		self.__key_modified['id'] = 1

	def get_start_date(self):
		"""
		The method to get the start_date

		Returns:
			datetime: An instance of datetime
		"""

		return self.__start_date

	def set_start_date(self, start_date):
		"""
		The method to set the value to start_date

		Parameters:
			start_date (datetime) : An instance of datetime
		"""

		from datetime import datetime

		if start_date is not None and not isinstance(start_date, datetime):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: start_date EXPECTED TYPE: datetime', None, None)

		self.__start_date = start_date
		self.__key_modified['start_date'] = 1

	def get_scheduled_date(self):
		"""
		The method to get the scheduled_date

		Returns:
			datetime: An instance of datetime
		"""

		return self.__scheduled_date

	def set_scheduled_date(self, scheduled_date):
		"""
		The method to set the value to scheduled_date

		Parameters:
			scheduled_date (datetime) : An instance of datetime
		"""

		from datetime import datetime

		if scheduled_date is not None and not isinstance(scheduled_date, datetime):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: scheduled_date EXPECTED TYPE: datetime', None, None)

		self.__scheduled_date = scheduled_date
		self.__key_modified['scheduled_date'] = 1

	def get_status(self):
		"""
		The method to get the status

		Returns:
			string: A string representing the status
		"""

		return self.__status

	def set_status(self, status):
		"""
		The method to set the value to status

		Parameters:
			status (string) : A string representing the status
		"""

		if status is not None and not isinstance(status, str):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: status EXPECTED TYPE: str', None, None)

		self.__status = status
		self.__key_modified['status'] = 1

	def get_requester(self):
		"""
		The method to get the requester

		Returns:
			Requester: An instance of Requester
		"""

		return self.__requester

	def set_requester(self, requester):
		"""
		The method to set the value to requester

		Parameters:
			requester (Requester) : An instance of Requester
		"""

		try:
			from zohocrmsdk.src.com.zoho.crm.api.backup.requester import Requester
		except Exception:
			from .requester import Requester

		if requester is not None and not isinstance(requester, Requester):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: requester EXPECTED TYPE: Requester', None, None)

		self.__requester = requester
		self.__key_modified['requester'] = 1

	def is_key_modified(self, key):
		"""
		The method to check if the user has modified the given key

		Parameters:
			key (string) : A string representing the key

		Returns:
			int: An int representing the modification
		"""

		if key is not None and not isinstance(key, str):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: key EXPECTED TYPE: str', None, None)

		if key in self.__key_modified:
			return self.__key_modified.get(key)

		return None

	def set_key_modified(self, key, modification):
		"""
		The method to mark the given key as modified

		Parameters:
			key (string) : A string representing the key
			modification (int) : An int representing the modification
		"""

		if key is not None and not isinstance(key, str):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: key EXPECTED TYPE: str', None, None)

		if modification is not None and not isinstance(modification, int):
			raise SDKException(Constants.DATA_TYPE_ERROR, 'KEY: modification EXPECTED TYPE: int', None, None)

		self.__key_modified[key] = modification


import cv2
import numpy as np

from .base import BaseTask

class BlurAndPHash(BaseTask):
    def __init__(self):
        super().__init__(taskID=4, taskName='BlurAndPHash')
        self.thresholdLaplacian = 120
        self.thresholdDiffStop = 120
        self.thresholdDiffPre = 25
        self.hashLen = 32
        self.preStopPHash = None
        self.prePHash = None
        self.n = 0

    def exec(self, inputData):
        frame, isLastFrame = inputData
        if isLastFrame:
            return None, isLastFrame

        currPHash = self.getPHash(frame)
        if currPHash is None:
            return None

        if self.preStopPHash is None:
            self.preStopPHash = currPHash
            self.prePHash = currPHash
            return frame, isLastFrame

        diffStop = self.hamDistance(self.preStopPHash, currPHash)
        diffPre = self.hamDistance(self.prePHash, currPHash)
        self.prePHash = currPHash

        if diffStop >= self.thresholdDiffStop \
                or diffPre <= self.thresholdDiffPre:
            return None

        self.n += 1
        if self.n <= 3:
            return None
        self.n = 0
        self.preStopPHash = currPHash
        return frame, isLastFrame

    def getPHash(self, img):
        pHash = None
        laplacian = cv2.Laplacian(img, cv2.CV_64F).var()
        if laplacian <= self.thresholdLaplacian:
            return pHash
        imgGray = cv2.resize(
            cv2.cvtColor(img, cv2.COLOR_RGB2GRAY),
            (self.hashLen, self.hashLen),
            cv2.INTER_AREA)
        height, width = imgGray.shape[:2]
        matrixOriginal = np.zeros(
            (height, width),
            np.float32)
        matrixOriginal[:height, :width] = imgGray

        matrix = cv2.dct(cv2.dct(matrixOriginal))
        matrix.resize(self.hashLen, self.hashLen)
        matrixFlatten = matrix.flatten()

        medianValue = sum(matrixFlatten) * 1. / len(matrixFlatten)
        pHash = 0
        for i in matrixFlatten:
            pHash <<= 1
            if i >= medianValue:
                pHash += 1
        return pHash

    @staticmethod
    def hamDistance(x, y):
        tmp = x ^ y
        distance = 0

        while tmp > 0:
            distance += tmp & 1
            tmp >>= 1

        return distance


# encoding=utf-8
import logging
import logging.config
import os
import sys
import time
import traceback
import datetime

def init_log(name='root'):
    path = os.path.dirname(__file__)

    config_file = path + os.sep + 'logger.conf'
    log_path = os.path.join(os.path.abspath(__file__ + ('/..' * 3)), 'zz_logs')
    if not os.path.exists(log_path):
        os.makedirs(log_path)

    log_path = os.path.join(log_path, str(datetime.datetime.now().date()) + '.log')

    if os.path.isfile(config_file) is False:
        raise Exception("Config file {} not found".format(config_file))

    datalines = list()
    with open(config_file, 'r') as f:
        for data in f.readlines():
            if '$path' in data:
                data = data.replace('$path', log_path)
            datalines.append(data)
    f = open(config_file + '_bak', 'w')
    f.writelines(datalines)
    f.close()

    del datalines

    logging.config.fileConfig(config_file + '_bak')

    # os.remove(config_file + '_bak')

    return logging.getLogger(name)

# decorator print log
def addlog(name=''):
    begin = time.time()

    def _addlog(func):
        def wapper(*args, **kwargs):
            data = None
            begin1 = time.time()
            try:
                s = traceback.extract_stack()
                file = s[-2][0]
                __project_name = os.path.abspath(__file__ + ('/..' * 3))
                file_name = file[file.find(__project_name) + len(__project_name) + 1:file.rfind(r'.')]
                func_descrip = (file_name + '.' + func.__name__) if name == '' else name

                log.info('Start Execute：%s ...' % func_descrip)
                data = func(*args, **kwargs)

                inner_secs = time.time() - begin1

                log.info('Complete：%s , Time Consume: %s, Total Time: %s ' % (func_descrip,
                                                         time_str(inner_secs), time_str(time.time() - begin)))

            except Exception as e:
                # traceback.print_exc()
                log.exception('Failure Calling Time Consume:%s, Total Time:%s, Err Message:%s', time_str(time.time() - begin1),
                              time_str(time.time() - begin), e)
                # traceback.print_exc(file=open(log_file, 'a'))
                sys.exit(0)

            return data

        return wapper

    return _addlog

def time_str(second):
    return ('%.2f sec' % second) if second < 60 else ('%.2f min' % (second / 60.0))

log = init_log()

# example
@addlog()
def log_test1():
    time.sleep(1)

@addlog(name='test2')
def log_test2():
    time.sleep(1)
    log_test1()
    time.sleep(2)
    raise ValueError('A very specific bad thing happened.')

if __name__ == "__main__":
    col = 'aaaa'
    missing_rate = 0.26587

    log.info('%s has missing rate as %f' % (col, missing_rate))
    # log_test2()
    #
    # __project_name = os.path.abspath(__file__ + ('/..' * 3))
    # print(__project_name)

    log.debug('debug')

    log.info('test  -   debug')

    log.warning('warining')


from metux.util.task import Task, TaskFail
from metux.util.git import GitRepo

"""Task: clone an git repo w/ initial checkout"""
class GitCloneTask(Task):

    def do_run(self):

        spec = self.param['spec']
        repo = GitRepo(spec['path'])
        repo.initialize()

        for remote in spec['remotes']:
            repo.set_remote(remote, spec['remotes'][remote]['url'])

        if repo.is_checked_out():
            if ('init-force' in spec) and spec['init-force']:
                self.log_info("forcing re-init to "+spec['init-ref'])
                repo.remote_update_all()
                repo.force_checkout(spec['init-ref'], spec['init-branch'])
            if ('remote-update' in spec) and spec['remote-update']:
                repo.remote_update_all()
        else:
            if (not 'init-ref' in spec) or (spec['init-ref'] is None):
                raise TaskFail(self, 'cant checkout "'+spec['path']+'": autobuild-ref not defined')
            else:
                self.log_info("running initial checkout of "+spec['init-ref'])
                if not repo.checkout(spec['init-ref'], spec['init-branch']):
                    raise TaskFail(self, 'cant checkout "'+spec['path']+'": git checkout failed')

        if spec.get('init-submodules', False):
            self.log_info("initializing submodules")
            repo.submodule_init()

        return True


from typing import *

import random
class Solution:
    def partition(self, nums, left, right):
        pivot = random.randint(left, right)
        nums[pivot], nums[right] = nums[right], nums[pivot]
        i = left
        for j in range(left, right):
            if nums[j] <= nums[right]:
                nums[i], nums[j] = nums[j], nums[i]
                i += 1
                if nums[j] == nums[right]:
                    self.found_n = True
                    self.n = nums[right]
        nums[i], nums[right] = nums[right], nums[i]
        return i
    def qselect(self, nums, left, right, k):
        if left == right:
            return left
        pivot = self.partition(nums, left, right)
        if self.found_n:
            return self.n
        if pivot == k:
            return pivot
        elif pivot > k:
            return self.qselect(nums, left, pivot-1, k)
        else:
            return self.qselect(nums, pivot+1, right, k)
    def repeatedNTimes(self, nums: List[int]) -> int:
        self.found_n = False
        self.n = None
        ans = self.qselect(nums, 0, len(nums)-1, len(nums)//2)
        if self.found_n:
            return self.n
        if ans+1 < len(nums) and nums[ans] == nums[ans+1]:
            return nums[ans+1]
        else:
            return nums[ans-1]

if __name__ == "__main__":
    s = Solution()

    assert s.repeatedNTimes([9,5,3,3]) == 3
    assert s.repeatedNTimes([4,1,7,0,0,9,0,0]) == 0
    assert s.repeatedNTimes([5,1,5,2,5,3,5,4]) == 5


"""Module containing class `UntagClipsCommand`."""

import logging
import random
import time

from django.db import transaction

from vesper.command.clip_set_command import ClipSetCommand
from vesper.django.app.models import Job, Tag, TagEdit, TagInfo
import vesper.command.command_utils as command_utils
import vesper.django.app.model_utils as model_utils
import vesper.util.archive_lock as archive_lock
import vesper.util.text_utils as text_utils
import vesper.util.time_utils as time_utils

_logger = logging.getLogger()

class TagClipsCommand(ClipSetCommand):

    extension_name = 'tag_clips'

    def __init__(self, args):

        super().__init__(args, True)

        get_opt = command_utils.get_optional_arg
        self._clip_count = get_opt('clip_count', args)

    def execute(self, job_info):
        self._job_info = job_info
        clip_indices = self._get_tag_clip_indices()
        self._tag_clips(clip_indices)
        return True

    def _get_tag_clip_indices(self):

        if self._clip_count is None:
            # tag all clips

            return None

        clip_count = self._count_clips()

        if clip_count <= self._clip_count:
            # tag all clips

            return None

        # If we get here, a clip count is specified and it is less than
        # the number of untagged clips.

        _logger.info('Getting indices of clips to tag...')

        indices = random.sample(range(clip_count), self._clip_count)

        return frozenset(indices)

    def _count_clips(self):

        value_tuples = self._create_clip_query_values_iterator()
        count = 0

        for station, mic_output, date, detector in value_tuples:

            clips = model_utils.get_clips(
                station=station,
                mic_output=mic_output,
                date=date,
                detector=detector,
                annotation_name=self._annotation_name,
                annotation_value=self._annotation_value,
                tag_name=self._tag_name,
                tag_excluded=True,
                order=False)

            count += clips.count()

        return count

    def _tag_clips(self, clip_indices):

        start_time = time.time()

        value_tuples = self._create_clip_query_values_iterator()

        clip_index = 0
        total_clip_count = 0
        total_tagged_count = 0

        for station, mic_output, date, detector in value_tuples:

            # Get clip for this station, mic_output, date, and detector.
            clips = model_utils.get_clips(
                station=station,
                mic_output=mic_output,
                date=date,
                detector=detector,
                annotation_name=self._annotation_name,
                annotation_value=self._annotation_value,
                tag_name=self._tag_name,
                tag_excluded=True,
                order=False)

            # Get list of clip IDs.
            clip_ids = clips.values_list('pk', flat=True)

            # Get IDs of clips to tag.
            tag_clip_ids = \
                self._get_tag_clip_ids(clip_ids, clip_index, clip_indices)
            clip_count = len(clip_ids)
            tagged_count = len(tag_clip_ids)
            clip_index += clip_count

            # Tag clips.
            try:
                self._tag_clip_batch(tag_clip_ids)
            except Exception as e:
                batch_text = \
                    _get_batch_text(station, mic_output, date, detector)
                command_utils.log_and_reraise_fatal_exception(
                    e, f'Tagging of clips for {batch_text}')

            # Log clip counts.
            if tagged_count == clip_count:
                prefix = 'Tagged'
            else:
                untagged_count = clip_count - tagged_count
                prefix = (
                    f'Tagged {tagged_count} and left untagged '
                    f'{untagged_count} of')
            count_text = text_utils.create_count_text(clip_count, 'clip')
            batch_text = _get_batch_text(station, mic_output, date, detector)
            _logger.info(f'{prefix} {count_text} for {batch_text}.')

            total_clip_count += clip_count
            total_tagged_count += tagged_count

        # Log total clip counts and tagging rate.
        if total_tagged_count == total_clip_count:
            prefix = 'Tagged'
        else:
            total_untagged_count = total_clip_count - total_tagged_count
            prefix = (
                f'Tagged {total_tagged_count} and left untagged '
                f'{total_untagged_count} of')
        count_text = text_utils.create_count_text(total_clip_count, 'clip')
        elapsed_time = time.time() - start_time
        timing_text = command_utils.get_timing_text(
            elapsed_time, total_clip_count, 'clips')
        _logger.info(f'{prefix} a total of {count_text}{timing_text}.')

    def _get_tag_clip_ids(self, clip_ids, start_clip_index, clip_indices):

        if clip_indices is None:
            # tagging all clips

            return clip_ids

        else:
            # not tagging all clips

            clip_index = start_clip_index
            tag_clip_ids = []

            for clip_id in clip_ids:

                if clip_index in clip_indices:
                    tag_clip_ids.append(clip_id)

                clip_index += 1

            return tag_clip_ids

    def _tag_clip_batch(self, clip_ids):

        with archive_lock.atomic():

            with transaction.atomic():

                # See note in untag_clips_command.py about maximum
                # chunk size. I'm not certain we have to do the same
                # thing here, but it seems likely that we do, for a
                # similar reason.
                max_chunk_size = 900

                tag_info = TagInfo.objects.get(name=self._tag_name)
                action = TagEdit.ACTION_SET
                creation_time = time_utils.get_utc_now()
                creating_job = Job.objects.get(id=self._job_info.job_id)

                for i in range(0, len(clip_ids), max_chunk_size):

                    chunk = clip_ids[i:i + max_chunk_size]

                    # Create tags.
                    Tag.objects.bulk_create([
                        Tag(
                            clip_id=clip_id,
                            info=tag_info,
                            creation_time=creation_time,
                            creating_user=None,
                            creating_job=creating_job,
                            creating_processor=None)
                        for clip_id in chunk])

                    # Create tag edits.
                    TagEdit.objects.bulk_create([
                        TagEdit(
                            clip_id=clip_id,
                            info=tag_info,
                            action=action,
                            creation_time=creation_time,
                            creating_user=None,
                            creating_job=creating_job,
                            creating_processor=None)
                        for clip_id in chunk])

def _get_batch_text(station, mic_output, date, detector):
    return (
        f'station "{station.name}", mic output "{mic_output.name}", '
        f'date {date}, and detector "{detector.name}"')


import re

import pep8
import six

"""
Guidelines for writing new hacking checks

 - Use only for Octavia specific tests. OpenStack general tests
   should be submitted to the common 'hacking' module.
 - Pick numbers in the range O3xx. Find the current test with
   the highest allocated number and then pick the next value.
 - Keep the test method code in the source file ordered based
   on the O3xx value.
 - List the new rule in the top level HACKING.rst file
 - Add test cases for each new rule to
   octavia/tests/unit/test_hacking.py

"""

log_translation = re.compile(
    r"(.)*LOG\.(audit|error|info|warn|warning|critical|exception)\(\s*('|\")")
author_tag_re = (re.compile("^\s*#\s*@?(a|A)uthor"),
                 re.compile("^\.\.\s+moduleauthor::"))
_all_hints = set(['_', '_LI', '_LE', '_LW', '_LC'])
_all_log_levels = {
    # NOTE(yamamoto): Following nova which uses _() for audit.
    'audit': '_',
    'error': '_LE',
    'info': '_LI',
    'warn': '_LW',
    'warning': '_LW',
    'critical': '_LC',
    'exception': '_LE',
}
log_translation_hints = []
for level, hint in six.iteritems(_all_log_levels):
    r = "(.)*LOG\.%(level)s\(\s*((%(wrong_hints)s)\(|'|\")" % {
        'level': level,
        'wrong_hints': '|'.join(_all_hints - set([hint])),
    }
    log_translation_hints.append(re.compile(r))

assert_trueinst_re = re.compile(
    r"(.)*assertTrue\(isinstance\((\w|\.|\'|\"|\[|\])+, "
    "(\w|\.|\'|\"|\[|\])+\)\)")
assert_equal_in_end_with_true_or_false_re = re.compile(
    r"assertEqual\((\w|[][.'\"])+ in (\w|[][.'\", ])+, (True|False)\)")
assert_equal_in_start_with_true_or_false_re = re.compile(
    r"assertEqual\((True|False), (\w|[][.'\"])+ in (\w|[][.'\", ])+\)")
assert_equal_with_true_re = re.compile(
    r"assertEqual\(True,")
assert_equal_with_false_re = re.compile(
    r"assertEqual\(False,")
mutable_default_args = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
assert_equal_end_with_none_re = re.compile(r"(.)*assertEqual\(.+, None\)")
assert_equal_start_with_none_re = re.compile(r".*assertEqual\(None, .+\)")
assert_not_equal_end_with_none_re = re.compile(
    r"(.)*assertNotEqual\(.+, None\)")
assert_not_equal_start_with_none_re = re.compile(
    r"(.)*assertNotEqual\(None, .+\)")
assert_no_xrange_re = re.compile(
    r"\s*xrange\s*\(")

def _directory_to_check_translation(filename):
    return True

def assert_true_instance(logical_line):
    """Check for assertTrue(isinstance(a, b)) sentences

    O316
    """
    if assert_trueinst_re.match(logical_line):
        yield (0, "O316: assertTrue(isinstance(a, b)) sentences not allowed")

def assert_equal_or_not_none(logical_line):
    """Check for assertEqual(A, None) or assertEqual(None, A) sentences,

    assertNotEqual(A, None) or assertNotEqual(None, A) sentences

    O318
    """
    msg = ("O318: assertEqual/assertNotEqual(A, None) or "
           "assertEqual/assertNotEqual(None, A) sentences not allowed")
    res = (assert_equal_start_with_none_re.match(logical_line) or
           assert_equal_end_with_none_re.match(logical_line) or
           assert_not_equal_start_with_none_re.match(logical_line) or
           assert_not_equal_end_with_none_re.match(logical_line))
    if res:
        yield (0, msg)

def no_translate_debug_logs(logical_line, filename):
    """Check for 'LOG.debug(_('

    As per our translation policy,
    https://wiki.openstack.org/wiki/LoggingStandards#Log_Translation
    we shouldn't translate debug level logs.

    * This check assumes that 'LOG' is a logger.
    O319
    """
    if _directory_to_check_translation(filename) and logical_line.startswith(
            "LOG.debug(_("):
        yield(0, "O319 Don't translate debug level logs")

def validate_log_translations(logical_line, physical_line, filename):
    # Translations are not required in the test directory
    if "octavia/tests" in filename:
        return
    if pep8.noqa(physical_line):
        return
    msg = "O320: Log messages require translations!"
    if log_translation.match(logical_line):
        yield (0, msg)

    if _directory_to_check_translation(filename):
        msg = "O320: Log messages require translation hints!"
        for log_translation_hint in log_translation_hints:
            if log_translation_hint.match(logical_line):
                yield (0, msg)

def use_jsonutils(logical_line, filename):
    msg = "O321: jsonutils.%(fun)s must be used instead of json.%(fun)s"

    # Some files in the tree are not meant to be run from inside Octavia
    # itself, so we should not complain about them not using jsonutils
    json_check_skipped_patterns = [
    ]

    for pattern in json_check_skipped_patterns:
        if pattern in filename:
            return

    if "json." in logical_line:
        json_funcs = ['dumps(', 'dump(', 'loads(', 'load(']
        for f in json_funcs:
            pos = logical_line.find('json.%s' % f)
            if pos != -1:
                yield (pos, msg % {'fun': f[:-1]})

def no_author_tags(physical_line):
    for regex in author_tag_re:
        if regex.match(physical_line):
            physical_line = physical_line.lower()
            pos = physical_line.find('moduleauthor')
            if pos < 0:
                pos = physical_line.find('author')
            return pos, "O322: Don't use author tags"

def assert_equal_true_or_false(logical_line):
    """Check for assertEqual(True, A) or assertEqual(False, A) sentences

    O323
    """
    res = (assert_equal_with_true_re.search(logical_line) or
           assert_equal_with_false_re.search(logical_line))
    if res:
        yield (0, "O323: assertEqual(True, A) or assertEqual(False, A) "
               "sentences not allowed")

def no_mutable_default_args(logical_line):
    msg = "O324: Method's default argument shouldn't be mutable!"
    if mutable_default_args.match(logical_line):
        yield (0, msg)

def assert_equal_in(logical_line):
    """Check for assertEqual(A in B, True), assertEqual(True, A in B),

    assertEqual(A in B, False) or assertEqual(False, A in B) sentences

    O338
    """
    res = (assert_equal_in_start_with_true_or_false_re.search(logical_line) or
           assert_equal_in_end_with_true_or_false_re.search(logical_line))
    if res:
        yield (0, "O338: Use assertIn/NotIn(A, B) rather than "
               "assertEqual(A in B, True/False) when checking collection "
               "contents.")

def no_log_warn(logical_line):
    """Disallow 'LOG.warn('

    O339
    """
    if logical_line.startswith('LOG.warn('):
        yield(0, "O339:Use LOG.warning() rather than LOG.warn()")

def no_xrange(logical_line):
    """Disallow 'xrange()'

    O340
    """
    if assert_no_xrange_re.match(logical_line):
        yield(0, "O340: Do not use xrange().")

def factory(register):
    register(assert_true_instance)
    register(assert_equal_or_not_none)
    register(no_translate_debug_logs)
    register(validate_log_translations)
    register(use_jsonutils)
    register(no_author_tags)
    register(assert_equal_true_or_false)
    register(no_mutable_default_args)
    register(assert_equal_in)
    register(no_log_warn)
    register(no_xrange)


import os
import pathlib
import pandas as pd
import keyring
import dropbox
from dropbox.exceptions import AuthError

# Directory
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

dropbox_home = "https://www.dropbox.com/home/"
dropbox_app = "MAD_WahooToGarmin"
dropbox_app_dir = "/Apps/WahooFitness/"
DROPBOX_ACCESS_TOKEN = keyring.get_password("dropbox", dropbox_app)

# https://practicaldatascience.co.uk/data-science/how-to-use-the-dropbox-api-with-python

def dropbox_connect():
    """Create a connection to Dropbox."""

    try:
        dbx = dropbox.Dropbox(DROPBOX_ACCESS_TOKEN)
    except AuthError as e:
        print("Error connecting to Dropbox with access token: " + str(e))
    return dbx

def dropbox_list_files(path):
    """Return a Pandas dataframe of files in a given Dropbox folder path in the Apps directory.
    """

    dbx = dropbox_connect()

    try:
        files = dbx.files_list_folder(path).entries
        files_list = []
        for file in files:
            if isinstance(file, dropbox.files.FileMetadata):
                metadata = {
                    "filename": file.name,
                    "path_display": file.path_display,
                    "client_modified": pd.Timestamp(file.client_modified).isoformat(),
                    "server_modified": pd.Timestamp(file.server_modified).isoformat(),
                }
                files_list.append(metadata)

        df = pd.DataFrame.from_records(files_list)
        return df.sort_values(by="server_modified", ascending=False)

    except Exception as e:
        print("Error getting list of files from Dropbox: " + str(e))

def dropbox_download_file(dropbox_file_path, local_file_path):
    """Download a file from Dropbox to the local machine."""

    try:
        dbx = dropbox_connect()

        with open(local_file_path, "wb") as f:
            metadata, result = dbx.files_download(path=dropbox_file_path)
            f.write(result.content)
    except Exception as e:
        print("Error downloading file from Dropbox: " + str(e))

def dropbox_upload_file(local_path, local_file, dropbox_file_path):
    """Upload a file from the local machine to a path in the Dropbox app directory.

    Args:
        local_path (str): The path to the local file.
        local_file (str): The name of the local file.
        dropbox_file_path (str): The path to the file in the Dropbox app directory.

    Example:
        dropbox_upload_file('.', 'test.csv', '/stuff/test.csv')

    Returns:
        meta: The Dropbox file metadata.
    """

    try:
        dbx = dropbox_connect()

        local_file_path = pathlib.Path(local_path) / local_file

        with local_file_path.open("rb") as f:
            meta = dbx.files_upload(
                f.read(), dropbox_file_path, mode=dropbox.files.WriteMode("overwrite")
            )

            return meta
    except Exception as e:
        print("Error uploading file to Dropbox: " + str(e))

if __name__ == "__main__":
    print("here")


"""empty message

Revision ID: a5cfe890710d
Revises: 7352c721e0a4
Create Date: 2023-05-28 16:47:42.177222

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = 'a5cfe890710d'
down_revision = '7352c721e0a4'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('images', schema=None) as batch_op:
        batch_op.drop_column('url_small')
        batch_op.drop_column('url_full')
        batch_op.drop_column('url_regular')

    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    with op.batch_alter_table('images', schema=None) as batch_op:
        batch_op.add_column(sa.Column('url_regular', sa.VARCHAR(length=500), autoincrement=False, nullable=True))
        batch_op.add_column(sa.Column('url_full', sa.VARCHAR(length=500), autoincrement=False, nullable=True))
        batch_op.add_column(sa.Column('url_small', sa.VARCHAR(length=500), autoincrement=False, nullable=True))

    # ### end Alembic commands ###


# Time: O(n)
# Space: O(n)

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> int:
        """
        Use cumulative sum, in each root to leaf path
        """
        run_map = collections.defaultdict(int)
        run_map[0] = 1

        run_sum = 0

        return self.dfs(root, run_map, sum, run_sum)

    def dfs(self, root, run_map, sum, run_sum):
        if not root:
            return 0

        run_sum+=root.val

        count = 0

        if run_sum-sum in run_map and run_map[run_sum-sum]>0:
            count+=run_map[run_sum-sum]

        run_map[run_sum]+=1

        left_count = self.dfs(root.left, run_map, sum, run_sum)
        right_count = self.dfs(root.right, run_map, sum, run_sum)

        run_map[run_sum]-=1

        return count+left_count+right_count


import requests
from bs4 import BeautifulSoup
import json

def get_description(url):
    response = requests.get(url)
    if response is not None:
        soup = BeautifulSoup(response.text, 'html.parser')

    description = {}

    l1 = []
    l2 = []
    for item in soup.find_all("span", class_="adPage__content__features__key"):
        if item is not None:
            l1.append(item.text)

    for item in soup.find_all("span", class_="adPage__content__features__value"):
        if item is not None:
            l2.append(item.text)

    for index in range(len(l2)):
        description[l1[index]] = l2[index]

    extra = []
    for index in range(len(l2)+1,len(l1)):
        extra.append(index)
    description['Extra_features'] = extra

    if soup.find('h1') is not None:
        car_model = soup.find('h1').text

    des = soup.find('div', class_=("adPage__content__description grid_18"))
    if des is not None:
        description["description"] = des.text
    print(description)
    desc = {}

    desc[car_model] = description

    file_name = "description"

    with open(file_name,"a") as json_file:
        json.dump(desc, json_file)


import re
import sys
import subprocess

class INA3221:
	I2C_ADDR = 0x40
	MANUFACTURER_ID_VALUE = 0x5449 #Texas Instruments
	DIE_ID_VALUE = 0x3220 #INA 3221
	class Reg:
		MANUFACTURER_ID = 0xFE
		DIE_ID = 0xFF
		CH1_SHUNT = 0x1
		CH1_BUS = 0x2
		ShiftChannel = 0x2

	@staticmethod
	def read(bus, register):
		reved = bus.read_word_data(INA3221.I2C_ADDR, register)
		#reverse bytes in word
		return  int.from_bytes(((reved + 2**16) % 2**16).to_bytes(2, byteorder='little'), byteorder='big', signed=False)

def pretty_floats(float_arr):
	return ["{0:05.2f}".format(f) for f in float_arr]
def get_power_data(pci_id):
	import smbus
	subprocess.run(["modprobe", "i2c-dev"])
	i2c_devs = subprocess.run(["i2cdetect", "-l"], capture_output=True, text=True).stdout.splitlines()
	i2c_dev_selected = [i.split("\t")[0] for i in i2c_devs if "NVIDIA i2c adapter 2 at "+pci_id in i]
	if len(i2c_dev_selected) != 1:
		print("Failed finding i2c adapter for NVIDIA gpu at " + pci_id)
		return None
	i2c_dev = i2c_dev_selected[0]
	print("Using ", i2c_dev)
	i2c_num = int(i2c_dev.split('-')[-1])
	bus = smbus.SMBus(i2c_num)
	if (
		INA3221.read(bus, INA3221.Reg.DIE_ID) != INA3221.DIE_ID_VALUE
		or INA3221.read(bus, INA3221.Reg.MANUFACTURER_ID) != INA3221.MANUFACTURER_ID_VALUE
		):
		print("Unknown I2C device")
		return None
	shunts = {
		"If all shunts r5":[1,1,1],
		"If shunts r5, r5, r2":[1,1,0]
	}
	powers = []
	for channel in range(3):
		shunt_millivolts_raw = INA3221.read(bus, INA3221.Reg.CH1_SHUNT + channel * INA3221.Reg.ShiftChannel)
		if shunt_millivolts_raw >= 0x8000: shunt_millivolts_raw -= 0x10000 #handle negative value during lite load
		shunt_millivolts = shunt_millivolts_raw * 5 / 1000.
		in_volts = INA3221.read(bus, INA3221.Reg.CH1_BUS + channel * INA3221.Reg.ShiftChannel)/1000.
		r2_r5_amps = [shunt_millivolts/2., shunt_millivolts/5.]
		r2_r5_powers = [in_volts * amps for amps in r2_r5_amps]
		powers.append(r2_r5_powers)
		print(
			*pretty_floats([in_volts]), " Volt (normal is 12.000)    [r2, r5]",
			*pretty_floats([shunt_millivolts]), "millivolts on shunt  ",
			pretty_floats(r2_r5_amps), "amps  ",
			pretty_floats(r2_r5_powers), "Watts")
	for sk, sv in shunts.items():
		watts = [powers[i][v] for i, v in enumerate(sv)]
		print(sk, pretty_floats(watts), " Total watts:", sum(watts))
	bus.close()

if len(sys.argv) != 2:
	print(
"""This program gets power info from nvidia GPUs using I2C busses provided by nvidia driver.
Direct I2C is risky and if something goes wrong

IT MAY BRICK YOUR DISPLAY OR GPU.

Use at your own risk!
Usage (as root): """+sys.argv[0]+""" PCI_ID
Where PCI_ID is id of nvidia gpu with ina3221 onboard chip, like 3:00
""")
	sys.exit(1)
try:
	get_power_data(sys.argv[1])
except:
	print("Error occured, are you runing as root and has python-smbus and i2cdetect installed?\n\n")
	raise

"""Example output for EVGA 980TI under load
Using  i2c-3
12.09  Volt (normal is 12.000)    [r2, r5] 15.76 millivolts on shunt   ['07.88', '03.15'] amps   ['95.25', '38.10'] Watts
12.17  Volt (normal is 12.000)    [r2, r5] 21.08 millivolts on shunt   ['10.54', '04.22'] amps   ['128.25', '51.30'] Watts
12.13  Volt (normal is 12.000)    [r2, r5] 38.44 millivolts on shunt   ['19.22', '07.69'] amps   ['233.10', '93.24'] Watts
If all shunts r5 [38.101376, 51.30028799999999, 93.240064]  Total watts: 182.641728
"""