Best Python code snippet using playwright-python
pseudobinary.py
Source:pseudobinary.py
1# coding: utf-82# Copyright (c) Mogroup @ University of Maryland, College Park3# Distributed under the terms of the MIT License.4import pandas5from pymatgen import Composition, Element6from pymatgen.analysis.phase_diagram import PhaseDiagram, GrandPotentialPhaseDiagram, GrandPotPDEntry7from pymatgen.analysis.reaction_calculator import ComputedReaction, ReactionError8from interface_stability.singlephase import VirtualEntry9__author__ = "Yizhou Zhu"10__copyright__ = ""11__version__ = "2.2"12__maintainer__ = "Yizhou Zhu"13__email__ = "yizhou.zhu@gmail.com"14__status__ = "Production"15__date__ = "Jun 10, 2018"16class PseudoBinary(object):17 """18 A class for performing analyses on pseudo-binary stability calculations.19 The algorithm is based on the work in the following paper:20 Yizhou Zhu, Xingfeng He, Yifei Mo*, âFirst Principles Study on Electrochemical and Chemical Stability of the21 Solid Electrolyte-Electrode Interfaces in All-Solid-State Li-ion Batteriesâ, Journal of Materials Chemistry A, 4,22 3253-3266 (2016)23 DOI: 10.1039/c5ta08574h24 """25 def __init__(self, entry1, entry2, entries=None, sup_el=None):26 comp1 = entry1.composition27 comp2 = entry2.composition28 norm1 = 1.0 / entry1.composition.num_atoms29 norm2 = 1.0 / entry2.composition.num_atoms30 self.entry1 = VirtualEntry.from_composition(entry1.composition * norm1, energy=entry1.energy * norm1,31 name=comp1.reduced_formula)32 self.entry2 = VirtualEntry.from_composition(entry2.composition * norm2, energy=entry2.energy * norm2,33 name=comp2.reduced_formula)34 if not entries:35 entry_mix = VirtualEntry.from_composition(comp1 + comp2)36 entries = entry_mix.get_PD_entries(sup_el=sup_el)37 entries += [entry1, entry2]38 self.PDEntries = entries39 self.PD = PhaseDiagram(entries)40 def __eq__(self, other):41 return self.__dict__ == other.__dict__42 def pd_mixing(self):43 """44 This function give the phase equilibria of a pseudo-binary in a closed system (PD).45 It will give a complete evolution profile for mixing ratio x change from 0 to 1.46 x is the ratio (both entry norm. to 1 atom/fu) or each entry47 """48 profile = get_full_evolution_profile(self.PD, self.entry1, self.entry2, 0.0, 1.0)49 cleaned = clean_profile(profile)50 return cleaned51 def get_printable_pd_profile(self):52 return self.get_printed_profile(self.pd_mixing())53 def get_printable_gppd_profile(self, chempots, gppd_entries=None):54 return self.get_printed_profile(self.gppd_mixing(chempots, gppd_entries=gppd_entries))55 def get_printed_profile(self, profile):56 """57 A general function to generate printable table strings for pseudo-binary mixing results58 """59 output = ['\n === Pseudo-binary evolution profile === ']60 df = pandas.DataFrame()61 rxn_e = []62 mutual_rxn_e = []63 E0 = -profile[0][1][1]64 E1 = -profile[-1][1][1]65 x1s, x2s, es, mes, pes = [], [], [], [], []66 for item in profile:67 ratio, (decomp, e) = item68 x1s.append(1-ratio)69 x2s.append(ratio)70 es.append(-e*1000)71 mes.append((-e - ratio * E1 - (1 - ratio) * E0) * 1000)72 pes.append(", ".join([x.name for x in decomp]))73 rxn_e.append(-e)74 mutual_rxn_e.append(((-e - ratio * E1 - (1 - ratio) * E0) * 1000))75 df["x({})".format(self.entry2.name)] = x1s76 df["x({})".format(self.entry1.name)] = x2s77 df["Rxn. E. (meV/atom)"] = es78 df["Mutual Rxn. E. (meV/atom)"] = mes79 df["Phase Equilibria"] = pes80 comments = ["" for _ in range(len(profile))]81 min_loc = list(df[df.columns[2:4]].idxmin())82 if min_loc[0] == min_loc[1]:83 comments[min_loc[0]] = 'Minimum'84 else:85 comments[min_loc[0]] = 'Rxn. E. Min.'86 comments[min_loc[1]] = 'Mutual Rxn. E. Min.'87 df["Comment"] = comments88 print_df = df.to_string(index=False, float_format='{:,.2f}'.format, justify='center')89 output.append(print_df)90 string = '\n'.join(output)91 return string92 def gppd_mixing(self, chempots, gppd_entries=None):93 """94 This function give the phase equilibria of a pseudo-binary in a open system (GPPD).95 It will give a complete evolution profile for mixing ratio x change from 0 to 1.96 x is the ratio (both entry norm. to 1 atom/fu(w/o open element) ) or each entry97 """98 open_el = list(chempots.keys())[0]99 el_ref = VirtualEntry.get_mp_entry(open_el)100 chempots[open_el] = chempots[open_el] + el_ref.energy_per_atom101 gppd_entry1 = GrandPotPDEntry(self.entry1, {Element[_]: chempots[_] for _ in chempots})102 gppd_entry2 = GrandPotPDEntry(self.entry2, {Element[_]: chempots[_] for _ in chempots})103 if not gppd_entries:104 gppd_entries = self.get_gppd_entries(open_el)105 gppd = GrandPotentialPhaseDiagram(gppd_entries, chempots)106 profile = get_full_evolution_profile(gppd, gppd_entry1, gppd_entry2, 0, 1)107 cleaned = clean_profile(profile)108 return cleaned109 def get_gppd_entries(self, open_el):110 if open_el in (self.entry1.composition + self.entry2.composition).keys():111 gppd_entries = self.PDEntries112 else:113 comp = self.entry1.composition + self.entry2.composition + Composition(open_el.symbol)114 gppd_entries = VirtualEntry.from_composition(comp).get_GPPD_entries(open_el)115 return gppd_entries116 def get_gppd_transition_chempots(self, open_el, gppd_entries=None):117 """118 This is to get all possible transition chemical potentials from PD (rather than GPPD)119 Still use pure element ref.120 # May consider supporting negative miu in the future121 """122 if not gppd_entries:123 gppd_entries = self.get_gppd_entries(open_el)124 pd = PhaseDiagram(gppd_entries)125 vaspref_mius = pd.get_transition_chempots(Element(open_el))126 el_ref = VirtualEntry.get_mp_entry(open_el)127 elref_mius = [miu - el_ref.energy_per_atom for miu in vaspref_mius]128 return elref_mius129 def gppd_scanning(self, open_el, mu_hi, mu_lo, gppd_entries=None, verbose=False):130 """131 This function is to do a (slightly smarter) screening of GPPD pseudo-binary in a given miu range132 This is a very tedious function, but mainly because GPPD screening itself is very tedious.133 :param open_el: open element134 :param mu_hi: chemical potential upper bound135 :param mu_lo: chemical potential lower bound136 :param gppd_entries: Supply GPPD entries manually. If you supply this, I assume you know what you are doing137 :param verbose: whether to prune the PE result table138 :return: a printable string of screening results139 """140 mu_lo, mu_hi = sorted([mu_lo, mu_hi])141 miu_E_candidates = [miu for miu in self.get_gppd_transition_chempots(open_el) if142 (miu - mu_lo) * (miu - mu_hi) <= 0]143 miu_E_candidates = [mu_hi] + miu_E_candidates + [mu_lo]144 duplicate_index = []145 if not gppd_entries:146 gppd_entries = self.get_gppd_entries(open_el)147 for i in range(1, len(miu_E_candidates) - 1):148 miu_left = (miu_E_candidates[i] + miu_E_candidates[i - 1]) / 2.0149 miu_right = (miu_E_candidates[i] + miu_E_candidates[i + 1]) / 2.0150 profile_left = self.gppd_mixing({open_el: miu_left}, gppd_entries)151 profile_right = self.gppd_mixing({open_el: miu_right}, gppd_entries)152 if judge_same_decomp(profile_left, profile_right):153 duplicate_index.append(i)154 miu_E_candidates = [miu_E_candidates[i] for i in range(len(miu_E_candidates)) if i not in duplicate_index]155 mu_hi, miu_low, PE = [], [], []156 mu_list, E_mutual_list, E_total_list = [], [], []157 for i in range(1, len(miu_E_candidates)):158 miu = (miu_E_candidates[i] + miu_E_candidates[i - 1]) / 2.0159 profile = self.gppd_mixing({open_el: miu}, gppd_entries)160 E0 = -profile[0][1][1]161 E1 = -profile[-1][1][1]162 min_mutual = min(profile, key=lambda step: (-step[1][1] - step[0] * E1 - (1 - step[0]) * E0))163 mu_hi.append(miu_E_candidates[i - 1])164 miu_low.append(miu_E_candidates[i])165 PE.append(", ".join(sorted([x.name for x in min_mutual[1][0]])))166 for i in range(len(miu_E_candidates)):167 profile_transition = self.gppd_mixing({open_el: miu_E_candidates[i]}, gppd_entries)168 E0 = -profile_transition[0][1][1]169 E1 = -profile_transition[-1][1][1]170 min_mutual_transition = min(profile_transition,171 key=lambda step: (-step[1][1] - step[0] * E1 - (1 - step[0]) * E0))172 mu_list.append(miu_E_candidates[i])173 E_mutual_list.append(174 (-min_mutual_transition[1][1] - min_mutual_transition[0] * E1 - (1 - min_mutual_transition[0]) * E0))175 E_total_list.append(-min_mutual_transition[1][1])176 to_be_hidden = []177 if not verbose:178 for i in range(1, len(PE)):179 if PE[i] == PE[i - 1]:180 to_be_hidden.append(i)181 mu_hi_display_list = [mu_hi[k] for k in range(len(mu_hi)) if k not in to_be_hidden]182 mu_low_display_list = mu_hi_display_list[1:] + [mu_lo]183 PE_display_list = [PE[k] for k in range(len(PE)) if k not in to_be_hidden]184 df1 = pandas.DataFrame()185 df2 = pandas.DataFrame()186 df1['mu_low'] = mu_hi_display_list187 df1['mu_high'] = mu_low_display_list188 df1['phase equilibria'] = PE_display_list189 df2['mu'] = mu_list190 df2['E_mutual(eV/atom)'] = E_mutual_list191 df2['E_total(eV/atom)'] = E_total_list192 print_df1 = df1.to_string(index=False, float_format='{:,.2f}'.format, justify='center')193 print_df2 = df2.to_string(index=False, float_format='{:,.2f}'.format, justify='center')194 output = [' == Phase Equilibria at min E_mutual == ', print_df1,'\n', ' == Reaction Energy ==',195 print_df2, 'Note: if E_mutual = 0, E_total is at x = 1 or 0']196 string = "\n".join(output)197 return string198"""199The following functions are auxiliary functions.200Most of them are used to solve or clean the mixing PE profile.201"""202def judge_same_decomp(profile1, profile2):203 """204 Judge whether two profiles have identical decomposition products205 """206 if len(profile1) != len(profile2):207 return False208 for step in range(len(profile1)):209 ratio1, (decomp1, e1) = profile1[step]210 ratio2, (decomp2, e1) = profile2[step]211 if abs(ratio1 - ratio2) > 1e-8:212 return False213 names1 = sorted([x.name for x in decomp1])214 names2 = sorted([x.name for x in decomp2])215 if names1 != names2:216 return False217 return True218def get_full_evolution_profile(pd, entry1, entry2, x1, x2):219 """220 This function is used to solve the transition points along a path on convex hull.221 The essence is to use binary search, which is more accurate and faster than brutal force screening222 This is a recursive function.223 :param pd: PhaseDiagram of GrandPotentialPhaseDiagram224 :param entry1 & entry2: mixing entry1/entry2, PDEntry for pd_mixing, GrandPotEntry for gppd_mixing225 :param x1 & x2: The mixing ratio range for binary search.226 :return: An uncleaned but complete profile with all transition points.227 """228 evolution_profile = {}229 entry_left = get_mix_entry({entry1: x1, entry2: 1 - x1})230 entry_right = get_mix_entry({entry1: x2, entry2: 1 - x2})231 (decomp1, h1) = pd.get_decomp_and_e_above_hull(entry_left)232 (decomp2, h2) = pd.get_decomp_and_e_above_hull(entry_right)233 decomp1 = set(decomp1.keys())234 decomp2 = set(decomp2.keys())235 evolution_profile[x1] = (decomp1, h1)236 evolution_profile[x2] = (decomp2, h2)237 if decomp1 == decomp2:238 return evolution_profile239 intersect = decomp1 & decomp2240 if len(intersect) > 0:241 # This is try to catch a single transition point242 try:243 rxn = ComputedReaction([entry_left, entry_right], list(intersect))244 if not {entry_left, entry_right} < set(rxn.all_entries):245 return evolution_profile246 c1 = rxn.coeffs[rxn.all_entries.index(entry_left)]247 c2 = rxn.coeffs[rxn.all_entries.index(248 entry_right)] # I know this is tedious but this is the only way I found that works..249 x = (c1 * x1 + c2 * x2) / (c1 + c2)250 if c1 * c2 == 0:251 return evolution_profile252 entry_mid = VirtualEntry.from_mixing({entry_left: c1 / (c1 + c2), entry_right: c2 / (c1 + c2)})253 h_mid = pd.get_decomp_and_e_above_hull(entry_mid)[1]254 evolution_profile[x] = (intersect, h_mid)255 return evolution_profile256 except ReactionError:257 pass258 x_mid = (x1 + x2) / 2.0259 entry_mid = get_mix_entry({entry1: 0.5, entry2: 0.5})260 (decomp_mid, h_mid) = pd.get_decomp_and_e_above_hull(entry_mid)261 decomp_mid = set(decomp_mid.keys())262 evolution_profile[x_mid] = (decomp_mid, h_mid)263 part1 = get_full_evolution_profile(pd, entry1, entry2, x1, x_mid)264 part2 = get_full_evolution_profile(pd, entry1, entry2, x_mid, x2)265 evolution_profile.update(part1)266 evolution_profile.update(part2)267 return evolution_profile268def clean_profile(evolution_profile):269 """270 This function is to clean the calculated profile from binary search. Redundant trial results are pruned out,271 with only transition points left.272 """273 raw_data = list(evolution_profile.items())274 raw_data.sort()275 clean_set = [raw_data[0]]276 for i in range(1, len(raw_data)):277 x, (decomp, h) = raw_data[i]278 x_cpr, (decomp_cpr, h_cpr) = clean_set[-1]279 if set(decomp_cpr) <= set(decomp):280 continue281 else:282 clean_set.append(raw_data[i])283 return clean_set284def get_mix_entry(mix_dict):285 """286 Mixing PDEntry or GrandPotEntry for the binary search algorithm.287 """288 entry1, entry2 = mix_dict.keys()289 x1, x2 = mix_dict[entry1], mix_dict[entry2]290 if type(entry1) == GrandPotPDEntry:291 mid_ori_entry = VirtualEntry.from_mixing({entry1.original_entry: x1, entry2.original_entry: x2})292 return GrandPotPDEntry(mid_ori_entry, entry1.chempots)293 else:...
theme.py
Source:theme.py
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3#4# Team:5# J Phani Mahesh <phanimahesh@gmail.com>6# Barneedhar (jokerdino) <barneedhar@ubuntu.com>7# Amith KK <amithkumaran@gmail.com>8# Georgi Karavasilev <motorslav@gmail.com>9# Sam Tran <samvtran@gmail.com>10# Sam Hewitt <hewittsamuel@gmail.com>11# Angel Araya <al.arayaq@gmail.com>12#13# Description:14# A One-stop configuration tool for Unity.15#16# Legal Stuff:17#18# This file is a part of Unity Tweak Tool19#20# Unity Tweak Tool is free software; you can redistribute it and/or modify it under21# the terms of the GNU General Public License as published by the Free Software22# Foundation; version 3.23#24# Unity Tweak Tool is distributed in the hope that it will be useful, but WITHOUT25# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS26# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more27# details.28#29# You should have received a copy of the GNU General Public License along with30# this program; if not, see <https://www.gnu.org/licenses/gpl-3.0.txt>31import os, os.path32from gi.repository import Gtk, Gio33from UnityTweakTool.config.ui import ui34from . import unitytweakconfig35from . import gsettings36class Themesettings ():37 def __init__(self, builder):38 self.ui=ui(builder)39 self.gtkthemestore=Gtk.ListStore(str,str)40 self.windowthemestore=self.gtkthemestore41 self.ui['tree_gtk_theme'].set_model(self.gtkthemestore)42 self.ui['tree_window_theme'].set_model(self.windowthemestore)43 # Get all themes44 systhdir='/usr/share/themes'45 systemthemes=[(theme.capitalize(),os.path.join(systhdir,theme)) for theme in os.listdir(systhdir) if os.path.isdir(os.path.join(systhdir,theme))]46 try:47 uthdir=os.path.expanduser('~/.themes')48 userthemes=[(theme.capitalize(),os.path.join(uthdir,theme)) for theme in os.listdir(uthdir) if os.path.isdir(os.path.join(uthdir,theme))]49 except OSError as e:50 userthemes=[]51 allthemes=systemthemes+userthemes52 allthemes.sort()53 required=['gtk-2.0','gtk-3.0','metacity-1']54 self.gtkthemes={}55 self.windowthemes={}56 for theme in allthemes:57 if all([os.path.isdir(os.path.join(theme[1],req)) for req in required]):58 iter=self.gtkthemestore.append(theme)59 themename=os.path.split(theme[1])[1]60 self.gtkthemes[themename]={'iter':iter,'path':theme[1]}61 self.windowthemes[themename]={'iter':iter,'path':theme[1]}62 self.iconthemestore=Gtk.ListStore(str,str)63 self.cursorthemestore=Gtk.ListStore(str,str)64 self.ui['tree_icon_theme'].set_model(self.iconthemestore)65 self.ui['tree_cursor_theme'].set_model(self.cursorthemestore)66 sysithdir='/usr/share/icons'67 systemiconthemes= [(theme.capitalize(),os.path.join(sysithdir,theme)) for theme in os.listdir(sysithdir) if os.path.isdir(os.path.join(sysithdir,theme))]68 to_be_hidden=[('Loginicons','/usr/share/icons/LoginIcons'),('Unity-webapps-applications','/usr/share/icons/unity-webapps-applications')]69 for item in to_be_hidden:70 try:71 systemiconthemes.remove(item)72 except ValueError as e:73 pass74 try:75 uithdir=os.path.expanduser('~/.icons')76 usericonthemes=[(theme.capitalize(),os.path.join(uithdir,theme)) for theme in os.listdir(uithdir) if os.path.isdir(os.path.join(uithdir,theme))]77 except OSError as e:78 usericonthemes=[]79 allithemes=systemiconthemes+usericonthemes80 allithemes.sort()81 self.iconthemes={}82 self.cursorthemes={}83 for theme in allithemes:84 iter=self.iconthemestore.append(theme)85 themename=os.path.split(theme[1])[1]86 self.iconthemes[themename]={'iter':iter,'path':theme[1]}87 if os.path.isdir(os.path.join(theme[1],'cursors')):88 iter=self.cursorthemestore.append(theme)89 self.cursorthemes[themename]={'iter':iter,'path':theme[1]}90 self.matchthemes=True91#=====================================================================#92# Helpers #93#=====================================================================#94 def refresh(self):95 # System theme96 gtkthemesel=self.ui['tree_gtk_theme'].get_selection()97 gtktheme=gsettings.gnome('desktop.interface').get_string('gtk-theme')98 # FIXME: Workaround to fix LP bug: #109884599 try:100 gtkthemesel.select_iter(self.gtkthemes[gtktheme]['iter'])101 # TODO: This except part should do something more.102 except KeyError:103 gtkthemesel.unselect_all()104 # Window theme105 windowthemesel=self.ui['tree_window_theme'].get_selection()106 windowtheme=gsettings.gnome('desktop.wm.preferences').get_string('theme')107 # FIXME: Workaround to fix LP bug: #1146122108 try:109 windowthemesel.select_iter(self.windowthemes[windowtheme]['iter'])110 # TODO: This except part should do a lot more.111 except KeyError:112 windowthemesel.unselect_all() 113 # Icon theme114 iconthemesel=self.ui['tree_icon_theme'].get_selection()115 icontheme=gsettings.gnome('desktop.interface').get_string('icon-theme')116 # FIXME: Workaround to fix potential bug117 try:118 iconthemesel.select_iter(self.iconthemes[icontheme]['iter'])119 except KeyError:120 iconthemesel.unselect_all()121 # Cursor theme122 cursorthemesel=self.ui['tree_cursor_theme'].get_selection()123 cursortheme=gsettings.gnome('desktop.interface').get_string('cursor-theme')124 # FIXME: Workaround to fix LP bug: #1097227125 try:126 cursorthemesel.select_iter(self.cursorthemes[cursortheme]['iter'])127 # TODO: except part should make sure the selection is deselected.128 except KeyError:129 cursorthemesel.unselect_all()130 # Cursor size131 self.ui['check_cursor_size'].set_active(True if gsettings.interface.get_int('cursor-size') is 48 else False)132 # ===== Fonts ===== #133 # Fonts134 self.ui['font_default'].set_font_name(gsettings.interface.get_string('font-name'))135 self.ui['font_document'].set_font_name(gsettings.interface.get_string('document-font-name'))136 self.ui['font_monospace'].set_font_name(gsettings.interface.get_string('monospace-font-name'))137 self.ui['font_window_title'].set_font_name(gsettings.wm.get_string('titlebar-font'))138 # Antialiasing139 if gsettings.antialiasing.get_string('antialiasing') == 'none':140 self.ui['cbox_antialiasing'].set_active(0)141 elif gsettings.antialiasing.get_string('antialiasing') == 'grayscale':142 self.ui['cbox_antialiasing'].set_active(1)143 elif gsettings.antialiasing.get_string('antialiasing') == 'rgba':144 self.ui['cbox_antialiasing'].set_active(2)145 # Hinting146 if gsettings.antialiasing.get_string('hinting') == 'none':147 self.ui['cbox_hinting'].set_active(0)148 elif gsettings.antialiasing.get_string('hinting') == 'slight':149 self.ui['cbox_hinting'].set_active(1)150 elif gsettings.antialiasing.get_string('hinting') == 'medium':151 self.ui['cbox_hinting'].set_active(2)152 elif gsettings.antialiasing.get_string('hinting') == 'full':153 self.ui['cbox_hinting'].set_active(3)154 # Scaling155 self.ui['spin_textscaling'].set_value(gsettings.interface.get_double('text-scaling-factor'))156#-----BEGIN: Theme settings------157# These check for nonetype and return since for some bizzare reason Gtk.quit destroys158# the selection object and then calls these callbacks. This is a temporary fix to LP:1096964159 # System Theme160 def on_treeselection_gtk_theme_changed(self,udata=None):161 gtktreesel = self.ui['tree_gtk_theme'].get_selection()162 if gtktreesel is None:163 return164 gtkthemestore,iter = gtktreesel.get_selected()165 if self.matchthemes:166 self.ui['treeselection_window_theme'].select_iter(iter)167 themepath=gtkthemestore.get_value(iter,1)168 theme=os.path.split(themepath)[1]169 gsettings.interface.set_string('gtk-theme',theme)170 def on_treeselection_window_theme_changed(self,udata=None):171 windowtreesel = self.ui['tree_window_theme'].get_selection()172 if windowtreesel is None:173 return174 windowthemestore,iter = windowtreesel.get_selected()175 if self.matchthemes:176 self.ui['treeselection_gtk_theme'].select_iter(iter)177 themepath=windowthemestore.get_value(iter,1)178 theme=os.path.split(themepath)[1]179 gsettings.wm.set_string('theme',theme)180 # Icon theme181 def on_tree_icon_theme_cursor_changed(self,udata=None):182 icontreesel = self.ui['tree_icon_theme'].get_selection()183 if icontreesel is None:184 return185 iconthemestore,iter = icontreesel.get_selected()186 themepath=iconthemestore.get_value(iter,1)187 theme=os.path.split(themepath)[1]188 gsettings.interface.set_string('icon-theme',theme)189 def on_check_show_incomplete_toggled(self,udata=None):190 # TODO191 print('To do')192 def on_b_theme_system_reset_clicked(self, widget):193 gsettings.interface.reset('gtk-theme')194 gsettings.wm.reset('theme')195 self.refresh()196#----- End: Theme settings------197#----- Begin: Icon settings--------198 def on_b_theme_icon_reset_clicked(self, widget):199 gsettings.interface.reset('icon-theme')200 self.refresh()201#----- End: Icon settings------202#----- Begin: Cursor settings--------203 # Cursor204 def on_tree_cursor_theme_cursor_changed(self,udata=None):205 cursortreesel= self.ui['tree_cursor_theme'].get_selection()206 if cursortreesel is None:207 return208 cursorthemestore,iter = cursortreesel.get_selected()209 themepath=cursorthemestore.get_value(iter,1)210 theme=os.path.split(themepath)[1]211 gsettings.interface.set_string('cursor-theme',theme)212 # Cursor Size213 def on_check_cursor_size_toggled(self, widget, udata = None):214 if self.ui['check_cursor_size'].get_active() == True :215 gsettings.interface.set_int('cursor-size', 48)216 else:217 gsettings.interface.set_int('cursor-size', 24)218 def on_b_theme_cursor_reset_clicked(self, widget):219 gsettings.interface.reset('cursor-theme')220 gsettings.interface.reset('cursor-size')221 self.refresh()...
song.py
Source:song.py
1from PyQt5 import QtWidgets2from PyQt5.QtCore import Qt, QMimeData3from PyQt5.QtGui import QDrag4from PyQt5.QtWidgets import QTableWidget, QAbstractItemView, QTableWidgetItem, QApplication5import customlogger as logger6from db import db7from gui.events.calculator_view_events import RequestSupportTeamEvent, SupportTeamSetMusicEvent8from gui.events.chart_viewer_events import SendMusicEvent, PopupChartViewerEvent9from gui.events.song_view_events import GetSongDetailsEvent10from gui.events.utils import eventbus11from gui.events.utils.eventbus import subscribe12from gui.viewmodels.mime_headers import MUSIC13from gui.viewmodels.utils import NumericalTableWidgetItem14from static.color import Color15from static.song_difficulty import Difficulty16class SongViewWidget(QTableWidget):17 def __init__(self, main, song_view, *args, **kwargs):18 super(SongViewWidget, self).__init__(main, *args, **kwargs)19 self.song_view = song_view20 def mousePressEvent(self, event):21 if event.button() == Qt.RightButton:22 if self.song_view.shifting:23 self.song_view.toggle_timers()24 else:25 self.song_view.toggle_percentage()26 return27 if event.button() == Qt.LeftButton:28 self.drag_start_position = event.pos()29 self.selected = self.selectedIndexes()30 super().mousePressEvent(event)31 def mouseMoveEvent(self, event):32 if not (event.buttons() & Qt.LeftButton):33 return34 if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():35 return36 if self.selectedItems():37 self.selected = self.selectedIndexes()38 if not self.selected:39 return40 drag = QDrag(self)41 mimedata = QMimeData()42 mimedata.setText(MUSIC + "|".join(map(str, self.song_view.model.get_song(GetSongDetailsEvent()))))43 drag.setMimeData(mimedata)44 drag.exec_(Qt.CopyAction | Qt.MoveAction)45 def keyPressEvent(self, event):46 if event.key() == Qt.Key_Shift:47 self.song_view.shifting = True48 def keyReleaseEvent(self, event):49 if event.key() == Qt.Key_Shift:50 self.song_view.shifting = False51class SongView:52 def __init__(self, main):53 self.widget = SongViewWidget(main, self)54 self.widget.setEditTriggers(QAbstractItemView.NoEditTriggers) # Disable edit55 self.widget.setVerticalScrollMode(1) # Smooth scroll56 self.widget.setHorizontalScrollMode(1) # Smooth scroll57 self.widget.verticalHeader().setVisible(False)58 self.widget.setSortingEnabled(True)59 self.widget.setDragEnabled(True)60 self.widget.setSelectionMode(QAbstractItemView.SingleSelection)61 self.widget.setSelectionBehavior(QAbstractItemView.SelectRows)62 self.widget.setToolTip("Right click to toggle note types between number and percentage.\n"63 "Shift-right click to toggle timer percentages.")64 self.model = False65 self.percentage = False66 self.timers = False67 self.shifting = False68 self.chart_viewer = None69 def set_model(self, model):70 self.model = model71 self.widget.cellClicked.connect(lambda r, _: self.model.ping_support(r))72 self.widget.cellDoubleClicked.connect(lambda r, _: self.model.popup_and_load_chart(r))73 def show_only_ids(self, live_detail_ids):74 if not live_detail_ids:75 live_detail_ids = set()76 else:77 live_detail_ids = set(live_detail_ids)78 for r_idx in range(self.widget.rowCount()):79 if int(self.widget.item(r_idx, 0).text()) in live_detail_ids:80 self.widget.setRowHidden(r_idx, False)81 else:82 self.widget.setRowHidden(r_idx, True)83 def load_data(self, data):84 DATA_COLS = ["LDID", "LiveID", "DifficultyInt", "ID", "Name", "Color", "Difficulty", "Level", "Duration (s)",85 "Note Count", "7h %", "9h %", "11h %", "12m %", "6m %", "9m %", "11m %", "13h %",86 "Tap", "Long", "Flick", "Slide", "Tap %", "Long %", "Flick %", "Slide %"]87 self.widget.setColumnCount(len(DATA_COLS))88 self.widget.setRowCount(len(data))89 self.widget.setHorizontalHeaderLabels(DATA_COLS)90 self.widget.setSortingEnabled(True)91 for r_idx, card_data in enumerate(data):92 for c_idx, (key, value) in enumerate(card_data.items()):93 if isinstance(value, int) and 21 >= c_idx >= 7 or c_idx == 1:94 item = NumericalTableWidgetItem(value)95 elif value is None:96 item = QTableWidgetItem("")97 else:98 item = QTableWidgetItem(str(value))99 self.widget.setItem(r_idx, c_idx, item)100 logger.info("Loaded {} charts".format(len(data)))101 self.widget.setColumnHidden(0, True)102 self.widget.setColumnHidden(2, True)103 self.widget.setSortingEnabled(True)104 self.widget.sortItems(3, Qt.AscendingOrder)105 self.toggle_percentage(change=False)106 self.toggle_timers(change=False)107 self.toggle_auto_resize(True)108 def toggle_timers(self, change=True):109 if change:110 self.timers = not self.timers111 if self.timers:112 for r_idx in range(10, 18):113 self.widget.setColumnHidden(r_idx, False)114 else:115 for r_idx in range(10, 18):116 self.widget.setColumnHidden(r_idx, True)117 def toggle_percentage(self, change=True):118 if change:119 self.percentage = not self.percentage120 if not self.percentage:121 for r_idx in range(22, 26):122 self.widget.setColumnHidden(r_idx, True)123 for r_idx in range(18, 22):124 self.widget.setColumnHidden(r_idx, False)125 else:126 for r_idx in range(22, 26):127 self.widget.setColumnHidden(r_idx, False)128 for r_idx in range(18, 22):129 self.widget.setColumnHidden(r_idx, True)130 def toggle_auto_resize(self, on=False):131 if on:132 self.widget.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)133 self.widget.horizontalHeader().setSectionResizeMode(4, QtWidgets.QHeaderView.Interactive)134 else:135 self.widget.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Interactive)136class SongModel:137 def __init__(self, view):138 assert isinstance(view, SongView)139 self.view = view140 eventbus.eventbus.register(self)141 def initialize_data(self):142 query = """143 SELECT ldc.live_detail_id as LDID,144 ldc.live_id as LiveID,145 ldc.difficulty as DifficultyInt,146 ldc.sort as ID,147 ldc.name as Name,148 ldc.color as Color,149 ldc.difficulty as Difficulty,150 ldc.level as Level,151 ldc.duration as Duration,152 CAST(ldc.Tap + ldc.Long + ldc.Flick + ldc.Slide AS INTEGER) as Notes,153 ldc.Timer_7h as Timer7h,154 ldc.Timer_9h as Timer9h,155 ldc.Timer_11h as Timer11h,156 ldc.Timer_12m as Timer12m,157 ldc.Timer_6m as Timer6m,158 ldc.Timer_9m as Timer9m, 159 ldc.Timer_11m as Timer11m,160 ldc.Timer_13h as Timer13h,161 ldc.Tap as Tap,162 ldc.Long as Long,163 ldc.Flick as Flick,164 ldc.Slide as Slide165 FROM live_detail_cache as ldc166 """167 data = db.cachedb.execute_and_fetchall(query, out_dict=True)168 checked_set = set()169 id_dict = dict()170 dupe_set = set()171 for _ in data:172 if _['DifficultyInt'] != 5:173 continue174 if _['Name'] not in checked_set:175 checked_set.add(_['Name'])176 id_dict[_['Name']] = list()177 else:178 dupe_set.add(_['Name'])179 id_dict[_['Name']].append(_['LiveID'])180 to_be_hidden = [max(id_dict[dupe]) for dupe in dupe_set]181 data = [182 _ for _ in data if _['DifficultyInt'] != 5 or _['LiveID'] not in to_be_hidden183 ]184 timers = ['7h', '9h', '11h', '12m', '6m', '9m', '11m', '13h']185 for _ in data:186 _['Color'] = Color(_['Color'] - 1).name187 _['Difficulty'] = Difficulty(_['Difficulty']).name188 _['Duration'] = "{:07.3f}".format(_['Duration'])189 _['TapPct'] = "{:05.2f}%".format(_['Tap'] / _['Notes'] * 100)190 _['LongPct'] = "{:05.2f}%".format(_['Long'] / _['Notes'] * 100)191 _['FlickPct'] = "{:05.2f}%".format(_['Flick'] / _['Notes'] * 100)192 _['SlidePct'] = "{:05.2f}%".format(_['Slide'] / _['Notes'] * 100)193 for timer in timers:194 key = 'Timer' + timer195 _[key] = "{:05.2f}%".format(_[key] * 100)196 self.view.load_data(data)197 @subscribe(GetSongDetailsEvent)198 def get_song(self, event=None):199 row_idx = self.view.widget.selectionModel().currentIndex().row()200 if row_idx == -1:201 return None, None, None, None, None202 live_detail_id = int(self.view.widget.item(row_idx, 0).text())203 score_id = int(self.view.widget.item(row_idx, 1).text())204 diff_id = int(self.view.widget.item(row_idx, 2).text())205 return score_id, diff_id, live_detail_id, \206 self.view.widget.item(row_idx, 4).text(), self.view.widget.item(row_idx, 6).text()207 def ping_support(self, r):208 song_id = int(self.view.widget.item(r, 1).text())209 difficulty = int(self.view.widget.item(r, 2).text())210 eventbus.eventbus.post(SendMusicEvent(song_id, difficulty))211 eventbus.eventbus.post(SupportTeamSetMusicEvent(song_id, difficulty))212 eventbus.eventbus.post(RequestSupportTeamEvent())213 def popup_and_load_chart(self, r):214 eventbus.eventbus.post(PopupChartViewerEvent())215 song_id = int(self.view.widget.item(r, 1).text())216 difficulty = int(self.view.widget.item(r, 2).text())...
launch_exec.py
Source:launch_exec.py
1# coding: utf-82# Copyright (c) 2001-2022, Hove and/or its affiliates. All rights reserved.3#4# This file is part of Navitia,5# the software to build cool stuff with public transport.6#7# Hope you'll enjoy and contribute to this project,8# powered by Hove (www.hove.com).9# Help us simplify mobility and open public transport:10# a non ending quest to the responsive locomotion way of traveling!11#12# LICENCE: This program is free software; you can redistribute it and/or modify13# it under the terms of the GNU Affero General Public License as published by14# the Free Software Foundation, either version 3 of the License, or15# (at your option) any later version.16#17# This program is distributed in the hope that it will be useful,18# but WITHOUT ANY WARRANTY; without even the implied warranty of19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the20# GNU Affero General Public License for more details.21#22# You should have received a copy of the GNU Affero General Public License23# along with this program. If not, see <http://www.gnu.org/licenses/>.24#25# Stay tuned using26# twitter @navitia27# channel `#navitia` on riot https://riot.im/app/#/room/#navitia:matrix.org28# https://groups.google.com/d/forum/navitia29# www.navitia.io30"""31Function to launch a bin32"""33from __future__ import absolute_import, unicode_literals34import subprocess35import os36import select37import re38import fcntl39import errno40class LogLine(object):41 def __init__(self, line):42 if line.startswith('DEBUG') or line.startswith('TRACE') or line.startswith('NOTICE') or not line:43 self.level = 1044 elif line.startswith('INFO'):45 self.level = 2046 elif line.startswith('WARN'):47 self.level = 3048 else:49 self.level = 4050 pos = line.find(' - ')51 if 0 < pos < 10:52 self.msg = line[pos + 3 :]53 else:54 self.msg = line55def parse_log(buff):56 logs = []57 line, sep, buff = buff.partition('\n')58 while sep and line:59 logs.append(LogLine(line))60 line, sep, buff = buff.partition('\n')61 if not sep:62 buff = line # we put back the last unterminated line in the buffer63 return logs, buff64# from: http://stackoverflow.com/questions/7729336/how-can-i-print-and-display-subprocess-stdout-and-stderr-output-without-distorti/7730201#773020165def make_async(fd):66 fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)67# Helper function to read some data from a file descriptor, ignoring EAGAIN errors68# (those errors mean that there are no data available for the moment)69def read_async(fd):70 try:71 return fd.read()72 except IOError as e:73 if e.errno != errno.EAGAIN:74 raise e75 else:76 return ''77def hide_args(whole_args, args_to_be_hidden):78 """hide the given args' contents.79 >>> hide_args(["--toto", "12345", "--titi", "my almighty password", "--tati", "hid args"], ["--titi", "--tati"])80 ['--toto', '12345', '--titi', 'xxxxxxxxx', '--tati', 'xxxxxxxxx']81 """82 args_copy = list(whole_args)83 for to_be_hidden in args_to_be_hidden:84 if args_copy.count(to_be_hidden) != 0:85 i = args_copy.index(to_be_hidden)86 args_copy[i + 1] = "xxxxxxxxx"87 return args_copy88def launch_exec_traces(exec_name, args, logger):89 """Launch an exec with args, log the outputs"""90 hidden_args = hide_args(args, ["--cities-connection-string", "--connection-string"])91 log = 'Launching ' + exec_name + ' ' + ' '.join(hidden_args)92 # we hide the password in logs93 logger.info(re.sub('password=\w+', 'password=xxxxxxxxx', log))94 args.insert(0, exec_name)95 proc = subprocess.Popen(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)96 traces = ""97 try:98 make_async(proc.stderr)99 make_async(proc.stdout)100 while True:101 select.select([proc.stdout, proc.stderr], [], [])102 for pipe in proc.stdout, proc.stderr:103 log_pipe = read_async(pipe)104 if log_pipe:105 logs, line = parse_log(log_pipe.decode("utf-8"))106 for l in logs:107 logger.log(l.level, l.msg)108 traces += "## {} ##".format(l.msg)109 if proc.poll() is not None:110 break111 finally:112 proc.stdout.close()113 proc.stderr.close()114 return proc.returncode, traces115def launch_exec(exec_name, args, logger):116 code, _ = launch_exec_traces(exec_name, args, logger)...
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!