so I am trying to create a bot in python, and for that cause I would need the size of the screen as two integers (x coordinate and y coordinate). I use pyautogui for that case, but the function size() only returns a string:
Size(width=2560, height=1440)
How would i go about "extracting" these values into integer variables?
edit: I managed to fix my problem, it's some spagetthi code, but I can clean it up later, just in case someone has the same problem:
import pyautogui
screen_size = str(pyautogui.size())
screen_size_x, screen_size_y = screen_size.split(",")
screen_size_x= screen_size_x.replace("Size(width=","")
screen_size_y = screen_size_y.replace("height=","")
screen_size_y = screen_size_y.replace(")","")
screen_size_y = screen_size_y.replace(" ","")
screen_size_x = int(screen_size_x)
screen_size_y = int(screen_size_y)
print(screen_size_x)
print(screen_size_y)
from inspect import getsource
print(getsource(pyautogui.size))
output:
def size():
"""Returns the width and height of the screen as a two-integer tuple.
Returns:
(width, height) tuple of the screen size, in pixels.
"""
return Size(*platformModule._size())
nicer code:
import pyautogui
x,y = pyautogui.size()
x,y=int(str(x)),int(str(y))
print(x)
print(y)
I've found multiple examples online of using pyautogui.size(). In all those examples, that method returns a two-item tuple containing width and height. So it seems that your code could be as simple as:
screen_size_x, screen_size_y = pyautogui.size()
print(screen_size_x)
print(screen_size_y)
This is shown in the first example in the pyautogui docs: https://github.com/asweigart/pyautogui/blob/master/README.md
If you did need to parse the string you mention, here's a cleaner way to do that:
import re
str = "Size(width=2560, height=1440)"
m = re.search(r"width=(\d+).*height=(\d+)", str)
screen_size_x, screen_size_y = int(m.group(1)), int(m.group(2))
print(screen_size_x)
print(screen_size_y)
Related
I have 10 objects, I would like to place these objects randomly within a range x, y, z (with minimum and maximum). Something like that:
import bpy
import bpy_extras
import random
import math
bpy.data.objects["Sasso_1"].select_set(True)
bpy.ops.rigidbody.objects_add(type='ACTIVE')
bpy.context.object.rigid_body.mass = 0.25
for obj in bpy.data.collections['Sassi'].all_objects:
obj.select_set(True)
bpy.ops.rigidbody.object_settings_copy()
bpy.ops.transform.translate(value=random.uniform(12,27), orient_axis='X')
bpy.ops.transform.translate(value=random.uniform(-15,15), orient_axis='Y')
bpy.ops.transform.translate(value=random.uniform(13,28), orient_axis='Z')
for obj in bpy.data.collections['Sassi'].all_objects:
bpy.ops.transform.rotate(value=random.uniform(0,360), orient_axis='X')
bpy.ops.transform.rotate(value=random.uniform(0,360), orient_axis='Y')
In my script, the objects "sassi" rotate and translate in a random way, but not in a range that I want.
The result is that the objects are unpredictable.
Tnx for the attention. :)
The translate operator does a relative movement:
https://docs.blender.org/api/blender_python_api_2_67_1/bpy.ops.transform.html
In your case you want to set an absolute position. How to do that is explained here:
https://blender.stackexchange.com/a/89581
bpy.data.objects["Cube"].location.x = 3.0
bpy.data.objects["Cube"].location.y = 2.0
bpy.data.objects["Cube"].location.z = 1.0
bpy.context.scene.update()
I resolve the problem with the randomize trasform function.
this is the code for do it:
bpy.ops.object.randomize_transform(random_seed = random.randint(0,100), loc=(6, 6, 6), scale=(1, 1, 1))
I am new to python and do not know it very well.
I want modified the online code to convert my image data to lmdb form.
I given the root of my src and dst like below:
paths_src = 'F:\caffe-windows\caffe-windows\data\sift-flow\test\'
path_dst = 'F:\caffe-windows\caffe-windows\data\sift-flow\testlmdb'
but after i run the code I got a error. it seem that my path is wrong? can anyone help? I also attach the code.
import os
import numpy as np
from scipy import io
import lmdb
import caffe
from PIL import Image
NUM_IDX_DIGITS = 10
IDX_FMT = '{:0>%d' % NUM_IDX_DIGITS + 'd}'
print '1111'
paths_src = 'F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\test\\'
path_dst = 'F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\testlmdb'
print '2222'
def img_to_lmdb(paths_src,path_dst):
in_db = lmdb.open(path_dst, map_size=int(1e9))
with in_db.begin(write=True) as in_txn:
for in_idx, in_ in enumerate(paths_src):
print 'img:::'+str(in_)
# load image:
# - as np.uint8 {0, ..., 255}
# - in BGR (switch from RGB)
# - in Channel x Height x Width order (switch from H x W x C)
im = np.array(Image.open(in_)) # or load whatever ndarray you need
im = im[:,:,::-1]
im = im.transpose((2,0,1))
im_dat = caffe.io.array_to_datum(im)
in_txn.put('{:0>10d}'.format(in_idx), im_dat.SerializeToString())
in_db.close()
img_to_lmdb(paths_src,path_dst)
print '3333'
I am not familiar with this library but your problem starts in this line-
for in_idx, in_ in enumerate(paths_src):
because paths_src is a string, which is iterable, the builtin function enumerate simply goes through each one of the characters in that string, so the first item would be the letter 'F' and not the entire path.
What you should do is define paths_src as a list. so instead of:
paths_src = 'F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\test\\'
you should do:
paths_src = ['F:\\caffe-windows\\caffe-windows\\data\\sift-flow\\test\\']
Hope I was helpful.
As far as I checked, the indentation is correct, no brackets are missing and I have only imported packages in the previous lines But I still get invalid syntax error.
#!/usr/bin/python
import bpy
import mathutils
import numpy as np
from math import radians
from mathutils import Vector
from math import radians
from mathutils import Matrix
from bpy import context
def transform_mesh('parent', 'obj_to_be_transformed', (translate_x, translate_y, translate_z), (rot_x,rot_y,rot_z)):
obj= bpy.data.objects[parent]
obj1= bpy.data.objects[obj_to_be_transformed]
initial_mat = obj1.matrix_world
...some code
(x,y,z) = (translate_x, translate_y, translate_z)
orig_loc_mat = Matrix.Translation(orig_loc+ mathutils.Vector((x,y,z)))
...some more code
eul = mathutils.Euler((radians(rot_x), radians(rot_y), radians(rot_z)), 'XYZ')
rot_mat = eul.to_matrix().to_4x4()
obj.matrix_world = orig_loc_mat * rot_mat * orig_rot_mat * orig_scale_mat
bpy.context.scene.update()
return [initial_loc,initial_rot,initial_scale,loc,rot,scale]
transform_result= transform_mesh('Armature','Coil',(5,0,0),(0,0,1))
print (transform_result)
And error is:
Error: File "D:\users\gayathri\Gayathri\Synthetic_data_generation\Final\HMI_Depth_coilA_final_final.blend\Untitled", line 18
def transform_mesh('parent', 'obj_to_be_transformed', (translate_x, translate_y, translate_z), (rot_x,rot_y,rot_z)):
^
SyntaxError: invalid syntax
location: <unknown location>:-1
def transform_mesh('parent', 'obj_to_be_transformed',
should be
def transform_mesh(parent, obj_to_be_transformed,
surely?
1- Remove strings from arguments
2- Remove tuples from arguments and attribute them in the function (It might be useful to add some checks)
So, here you are:
def transform_mesh(parent, obj_to_be_transformed, translate, rot):
translate_x, translate_y, translate_z= translate
rot_x,rot_y,rot_z = rot
# etc
transform_result= transform_mesh('Armature','Coil',(5,0,0),(0,0,1))
print (transform_result)
Tuple parameters are not supported in Python3, but you can pass it as a variable and unpack it after defining the function.
def transform_mesh(translate_xyz):
translate_x, translate_y, translate_z = translate_xyz
You need to provide variables as arguments to the function.
try something like:
def transform_mesh(parent, obj_to_be_transformed, t1, t2):
Although in the code you have shared, you are always using t1 and t2 as tuples. But in case you want to use x, y and z separately, you can do it by referencing the index:
x = t1[0]
y = t1[1]
In this line the function parameter are passed in incorrect way,
def transform_mesh('parent', 'obj_to_be_transformed', (translate_x, translate_y, translate_z), (rot_x,rot_y,rot_z)):
The Correct syntax would be:
def transform_mesh(parent, obj_to_be_transformed, *translate_xyz, *rot_xyz): #*translate_xyz and *rot-xyz are tuple parameter
I have a very annoying output format from a program for my x,y,r values, namely:
circle(201.5508,387.68505,2.298685) # text={1}
circle(226.21442,367.48613,1.457215) # text={2}
circle(269.8067,347.73605,1.303065) # text={3}
circle(343.29599,287.43024,6.5938) # text={4}
is there a way to get the 3 numbers out into an array without doing manual labor?
So I want the above input to become
201.5508,387.68505,2.298685
226.21442,367.48613,1.457215
269.8067,347.73605,1.303065
343.29599,287.43024,6.5938
if you mean that the circle(...) construct is the output you want to parse. Try something like this:
import re
a = """circle(201.5508,387.68505,2.298685) # text={1}
circle(226.21442,367.48613,1.457215) # text={2}
circle(269.8067,347.73605,1.303065) # text={3}
circle(343.29599,287.43024,6.5938) # text={4}"""
for line in a.split("\n"):
print [float(x) for x in re.findall(r"\d+(?:\.\d+)?", line)]
Otherwise, you might mean that you want to call circle with numbers taken from an array containing 3 numbers, which you can do as:
arr = [343.29599,287.43024,6.5938]
circle(*arr)
A bit unorthodox, but as the format of your file is valid Python code and there are probably no security risks regarding untrusted code, why not just simply define a circle function which puts all the circles into a list and execute the file like:
circles = []
def circle(x, y, r):
circles.append((x, y, r))
execfile('circles.txt')
circles is now list containing triplets of x, y and r:
[(201.5508, 387.68505, 2.298685),
(226.21442, 367.48613, 1.457215),
(269.8067, 347.73605, 1.303065),
(343.29599, 287.43024, 6.5938)]
I am using wxPython's HyperTreeList and I want to set the column width exactly equal to length of the largest string in it.
To accomplish that, I'd like to to convert a python string size into pixels.
For Example: If we have a string like
str = "python"
len(str) = 6
How could I convert the above string length/size into pixels?
Is there another way?
You'll have to do something like (see the documentation of wxWidgets for more info)
f = window.GetFont()
dc = wx.WindowDC(window)
dc.SetFont(f)
width, height = dc.GetTextExtent("Text to measure")
It depends on how you are printing the text.
You may be interested by PIL ImageDraw which has a textsize method. See http://effbot.org/imagingbook/imagedraw.htm
Update: This was answering the original question. It may looks a little off-topic after question updates.
This is not my solution, I'm just passing it on as I found it works and
most useful
as in a program environment it reduces to only 3 lines. Python3.9 mac OS
from tkinter import *
from tkinter import font as W1
FW=Tk() ; FW.withdraw() # a must but don't need a window
Text ='1234567890'
def LENGTH(Text) :
W2 = W1.Font(family='Comicsans' , size = 20)
length = W2.measure(Text)
print(length)
LENGTH(Text)