(Solved) Blender 3.4 Crashing When Attempting to Run Python Script - python

I'm attempting to run a script that's meant to take an initial input for the amount of vertices I want on an object for it to make and a secondary string for the coordinates that I want it to set to each vertex. The problem is that it crashes right when I hit run. File named "setCoordinates.py".
import bpy
def create_object(num_vertices, coordinates_str):
# Split into different strings for each vertex
coordinate_strs = coordinates_str.strip().split("X: ")
# Create a new mesh and object
mesh = bpy.data.meshes.new("MyMesh")
obj = bpy.data.objects.new("MyObject", mesh)
bpy.context.collection.objects.link(obj)
# Create a list to store the vertices
vertices = []
# Loop through the coordinate strings and add each vertex to the list
for i in range(1, num_vertices + 1):
# Split the current coordinate string into the X, Y, and Z components
x, y, z = coordinate_strs[i].strip().split("Y: ")[1].strip().split("Z: ")
# Add the vertex to the list
vertices.append((float(x), float(y), float(z)))
# Set the vertices of the mesh
mesh.from_pydata(vertices, [], [])
mesh.update()
# Get the number of vertices
num_vertices_str = input("Enter the number of vertices: ")
#Get the coordinate string
coordinates_str = input("Enter the vertex coordinates: ")
# Convert the number of vertices string to an integer
num_vertices = int(num_vertices_str)
create_object(num_vertices, coordinates_str)
I have an empty project with just an isosphere in it. I've tried to rearrange the code, and remove entire blocks, but it does the same thing. I've ran it in the Text Editor.

I tried running your script in Blender 3.4.1 and it worked. I think what happened is that Blender was waiting for your input so it looked like a crash. Since you're using the input Python function, the program won't continue until you enter the input in the terminal. There's a terminal window that automatically opens when you run Blender and the input prompts will appear there.
Also I changed this part of the program (line 16) because there was an error:
for coord_str in coordinate_strs[1:]:
# Split the current coordinate string into the X, Y, and Z components
coord_str = coord_str.split(" Y: ")
x = coord_str[0]
coord_str = coord_str[1].split(" Z: ")
y = coord_str[0]
z = coord_str[1]

Related

Python dictionary keys seem to vanish before I delete them

I'm a newbie programmer working on an idea for a small game. I wanted my play space to be a grid for various reasons. Without a lot of good reason, I decided to create a class of GridSquare objects, each object having properties like size, an index to describe what (x,y) coordinates they represented, and some flags to determine if the grid squares were on land or empty space, for example. My grid is a dictionary of these objects, where each GridSquare is a key. The values in the dictionary are going to be various objects in the place space, so that I can easily look up which objects are on each grid square.
Just describing this I feel like a complete lunatic. Please bear in mind that I've only been at this a week.
My problem appears when I try to change the GridSquare objects. For example, I want to use a list to generate the land on each level. So I iterate over the list, and for each value I look through my grid squares using a for loop until I find one with the right index, and flip the GridSquare.land property. But I found that this caused a runtime error, since I was changing keys in a dictionary I was looping through. OK.
Now what I'm trying to do is to create a list of the keys I want to change. For each item in my level-generating list, I go through all the GridSquares in my grid dictionary until I find the one with the index I'm looking for, then I append that GridSquare to a list of old GridSquares that need updating. I then make another copy of the GridSquare, with some properties changed, in a list of altered GridSquares. Finally, I delete any keys from my grid dictionary which match my list of "old" GridSquares, and then add all of the altered ones into my grid dictionary.
The problem is that when I delete keys from my grid dictionary which match my list of "old" keys, I run into keyerrors. I can't understand what is happening to my keys before I can delete them. Using try/except, I can see that it's only a small number of the keys, which seems to vary kind of arbitrarily when I change parts of my code.
I would appreciate any insight into this behaviour.
Here is code for anyone still reading:
aspect_ratio = (4, 3)
screen_size = (1280, 720)
#defining a class of objects called GridSquares
class GridSquare:
def __init__(self, x, y):
self.index = (x, y)
self.land = 0
#creates a dictionary of grid squares which I hope will function as a grid......
grid = {}
for x_index in range(1, (aspect_ratio[0] + 1)):
for y_index in range (1, (aspect_ratio[1] + 1)):
new_square = GridSquare(x_index, y_index)
grid[new_square] = None
#these are lists to hold changes I need to make to the dictionary of grid squares
grid_changes = []
old_gridsquares = []
#this unweildly list is meant to be used to generate a level. Numbers represent land, spaces are empty space.
for number_no, number in enumerate(["1", "1", "1", "1",
" ", " ", " ", " ",
"1", "1", "1", "1"]):
#makes grid squares land if they are designated as such in the list
for gridsquare in grid.keys():
#this if statement is meant to convert each letter's position in the list into an index like the grid squares have.
if gridsquare.index == ((number_no + 1) % (aspect_ratio[0]), ((number_no + 1) // (aspect_ratio[0] + 1)) + 1):
#create a list of squares that need to be updated, and a list of squares to be deleted
old_gridsquares.append(gridsquare)
flagged_gridsquare = GridSquare((number_no + 1) % (aspect_ratio[0]), ((number_no + 1) // (aspect_ratio[0] + 1)) + 1)
flagged_gridsquare.land = 1
#this part is meant to set the flag for the gridsquare that indicates if it is on the far side or the near side,
#if it is land
if number == "1":
flagged_gridsquare.near = 1
grid_changes.append(flagged_gridsquare)
#deletes from grid any items with a key that matches the old squares, and adds updated versions.
for old_gridsquare in old_gridsquares:
try:
del grid[old_gridsquare]
except:
print(old_gridsquare.index)
print(old_gridsquare.land)
for grid_change in grid_changes:
grid[grid_change] = None

How To Print Grid In Python Without "Flashing" Screen

In the program I've been working on in Python, I need to be able to print a list of elements one by one, going to a new line after n elements to form a grid. However, every time the program reprints the grid, you can see it progressing element by element, which looks rather ugly and distracting to the user. I was wondering if there was a way to "pause" the console output for a brief amount of time to allow the grid to be printed, then show the grid afterwards, erasing the previous printout, as to not show it printing element by element. The reason I need to do this is because the program uses Colorama for colored outputs, but different elements in the list will need to have different colors, meaning each element has to be printed one by one.
EDIT (Current code):
import time as t
from os import system as c
h = 50
w = 50
loop1 = 0
ostype = "Windows"
def cl():
if(ostype == "Linux"):
c('clear')
if(ostype == "Windows"):
c('cls')
def do():
grid = []
for x in range(0,h):
temp = []
for z in range(0,w):
temp.append("#")
grid.append(temp)
for a in range(0,h):
for b in range(0,w):
print(grid[a][b], flush=False, end="")
print()
while(loop1 == 0):
do()
t.sleep(1)
cl()
You can probably tell print to not to flush the standard out buffer, and have the last print to flush everything. Depends on what version of python you're using, for python 3 print function takes a flush argument, set that to true/false accordingly.

How to a get specific part of an input in Python, and multi paragraph input

This is a two-part question. I am working on making a Ti-basic emulator/translator in Python 3. What I want is to have something like:
0->N
while N<20
disp "example"
input "example",a
N+1->N
end
Which is the Ti-basic equivalent to this in Python:
for n in range(0,20):
print("Example")
a=input("Example")
In a more simplified way, I want it so if it says Disp "example" on line one, to translate it to Python as:
print((text in quotations after disp, "Example" in this case))
The two questions:
One:
How do I separate sections of an input, so that when whatever line it is that has disp knows to put print() and to put the area with quotations in the parenthesis of the print?
Two:
How do I get an input with multiple lines, so I don't have to type the Ti-basic line by line, per input, and to save it when I run it, like if you go to an online emulator?
a = [] #Create a list to store your values
for n in range (0, 20):
print('Example')
a.append('Example') #Add 'Example' string to list
print (a) #See all items in the list
If you want user to key in inputs 1 by 1:
a = [] #Create a list to store your values
for n in range (0, 20):
sample = input('Please key in your input: ') #Be aware that inputs are by default str type in Python3
a.append(sample) #Add sample string to list
print (a) #See all items in the list
#Declare a list
a = []
#Set a range for loop where N<20.
for x in range (19):
#Display "Example"
print("Example")
#Append "Example" to your 'a' list.
a.append("Example")
# printing the list using loop
for x in range(len(a)):
print a[x]

Need help editing a value in a list from a text file.

I am not able to add a number to my list that i have in a text file and don't know how to.
Code so far:
def add_player_points():
# Allows the user to add a points onto the players information.
L = open("players.txt","r+")
name = raw_input("\n\tPlease enter the name of the player whose points you wish to add: ")
for line in L:
s = line.strip()
string = s.split(",")
if name == string[0]:
opponent = raw_input("\n\t Enter the name of the opponent: ")
points = raw_input("\n\t Enter how many points you would like to add?: ")
new_points = string[5] + points
L.close()
This is a sample of a key in the text file. There are about 100 in the file:
Joe,Bloggs,J.bloggs#anemailaddress.com,01269 512355, 1, 0, 0, 0,
^
The value that i would like this number to be added to is the 0 besides the number already in there, indicated by an arrow below it. The text file is called players.txt as shown.
A full code answer would be helpful.
This is likely the problem:
new_points = string[5] + points
You are adding a string with another string, you need to convert them to integer
new_points = int(string[5]) + int(points)
This is not checking for incorrect input, but assuming the file format is correct and the user input too, it should work.
Edit: If you want to update the file with the new information, a better way is to divide the problem in 3 parts: 1) Read player information into an appropriate data structure, e.g. a dictionary using the player name as key, 2) Make the changes into the dictionary, and finally 3) save the changes back to file. So your code should be split into 3 functions. Some help can be found here.

"Amazing" from 101 BASIC Computer Games in Python

I'm trying to write a program that duplicates the "Amazing" game from 101 BASIC Computer Games, in Python. I want it to create the same text mazes using the same characters, and so far I am limiting myself to a program that I can run from a command line, without creating a new GUI. My research has led me to the Wikipedia article "Maze Generation Algorithm" and the page "Think Labyrinth: Maze Algorithms," from the astrolog.org website.
My first thought was to write a program that would build the maze from nothing, but the majority opinion about maze creation seems to be to start with a grid, start at a cell, then write an algorithm that tests the cell's neighbors to see if they have been visited, and break down the wall between the current cell and a random new neighbor that hasn't been visited already.
So far, I have written a program that will generate the text grid according to user input of width and height:
"""Asks user for a width and height, then generates a text grid based on
user input."""
#Only two imports
import random
import sys
width1 = int(input("What width do you want? "))
height1 = int(input("What height do you want? "))
#Text elements for the grid
top_Line = ".--"
top_End = "."
mid_Line = ":--"
mid_End = ":"
yes_Wall = " I"
def grid_Top(width1):
"""Draws the top of a grid of user width."""
top_Lst = []
for i in range(width1):
top_Lst.append(top_Line)
top_Lst.append(top_End)
return top_Lst
def grid_Walls(width1):
"""Draws the walls of the grid."""
walls_Lst = []
walls_Lst.append("I")
for i in range(width1):
walls_Lst.append(yes_Wall)
return walls_Lst
def grid_Floors(width1):
"""Draws the floors of the grid."""
floors_Lst = []
for i in range(width1):
floors_Lst.append(mid_Line)
floors_Lst.append(mid_End)
return floors_Lst
def grid_Create(width1, height1):
"""Creates the grid of user width & height."""
for i in grid_Top(width1):
print(i, end = "")
print("")
for j in range(height1):
for i in grid_Walls(width1):
print(i, end="")
print("")
for i in grid_Floors(width1):
print(i, end="")
print("")
grid_Create(width1, height1)
So, as it stands, each of my cells is defined by the ceiling above it, the walls to either side, and the floor below it. As it stands, this means that testing each cell for whether it has been visited or is intact involves looking at three lists - the previous list, the current list, and the next list, if you get my meaning.
My question is: How do I impose a structure onto my text grid so that each cell is its own entity, which can be tested for whether it has been visited in a depth-first search?
Any and all comments about my code will be welcome, whether or not they are relevant to the actual question I am asking!
Thanks!
I would use a set to explicitly track which cells have been visited:
visited = set()
if candidate_coord not in visited:
visited.add(candidate_coord)
break_wall(candidate_coord, curr_coord)

Categories

Resources