python error FPDF object has no attribute 'y' - python

I try to make save as button in plugin QGIS Dufour 2.01 and want to save it as pdf file
when i try save my file ( open file destination and then click save ) i got a error message
This code i wrote
def _save(self, simpan):
import fpdf
# Portrait, millimeter units, A4 page size
pdf=fpdf.FPDF("P", "mm", "A4")
# Set font: Times, normal, size 10
pdf.set_font('Times','', 12)
# Layout cell: 0 x 5 mm, text, no border, Left
pdf.cell(0,5,'Input 1 : ' + self.ui.lineInput1.text(),border=0,align="L")
pdf.cell(0,5,'Input 2 : ' + self.ui.lineInput2.text(), border=0,align="L")
pdf.cell(0,5,'Recomendation : ' + self.ui.textRec2.toPlainText(), border=0, align="L")
pdf.cell(0,5,'Data 1 :' + self.ui.lineCond1.text(), border=0, align="L" )
pdf.cell(0,5,'Data 2 :' + self.ui.lineCond2.text(), border=0, align="L" )
pdf.output( simpan+'.pdf','F')
Error message i get
File "C:\PROGRA~1\QGISDU~1\apps\Python27\lib\site-packages\fpdf\fpdf.py", line 615, in cell
if(self.y+h>self.page_break_trigger and not self.in_footer and self.accept_page_break()):
AttributeError: 'FPDF' object has no attribute 'y'
Python version:
2.7.4 (default, Apr 6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)]
i use fpdf 1.7 and install it with .msi installer

It seems you have not added a page to your pdf, before populating it with cells.
Try calling pdf.add_page() just after pdf=fpdf.FPDF("P", "mm", "A4")

add a page
def _save(self, simpan):
import fpdf
# Portrait, millimeter units, A4 page size
pdf=fpdf.FPDF("P", "mm", "A4")
# add a page
pdf.add_page()
# Set font: Times, normal, size 10
pdf.set_font('Times','', 12)
# Layout cell: 0 x 5 mm, text, no border, Left
pdf.cell(0,5,'Input 1 : ' + self.ui.lineInput1.text(),border=0,align="L")
pdf.cell(0,5,'Input 2 : ' + self.ui.lineInput2.text(), border=0,align="L")
pdf.cell(0,5,'Recomendation : ' + self.ui.textRec2.toPlainText(), border=0, align="L")
pdf.cell(0,5,'Data 1 :' + self.ui.lineCond1.text(), border=0, align="L" )
pdf.cell(0,5,'Data 2 :' + self.ui.lineCond2.text(), border=0, align="L" )
pdf.output( simpan+'.pdf','F')`

Related

tkinter python script crashes when opening from mac command line

So I am trying to make a small GUI in python (version 3.8.3) using tkinter. I wrote the whole script in the PyCharm IDE and I was able to run it without issue and still can. However trying to run it from the command line results in a crash and I get the following output:
2020-07-25 22:22:57.888 Python[69416:1640503] -[SDLApplication
_setup:]: unrecognized selector sent to instance 0x7ffcdd2ad590 2020-07-25 22:22:57.890 Python[69416:1640503] *** Terminating app due
to uncaught exception 'NSInvalidArgumentException', reason:
'-[SDLApplication _setup:]: unrecognized selector sent to instance
0x7ffcdd2ad590'
*** First throw call stack: ( 0 CoreFoundation 0x00007fff378a7797 __exceptionPreprocess + 250 1 libobjc.A.dylib
0x00007fff7073aa9e objc_exception_throw + 48 2 CoreFoundation
0x00007fff379269a6 -[NSObject(NSObject) __retain_OA] + 0 3
CoreFoundation 0x00007fff3780bf30
forwarding + 1427 4 CoreFoundation 0x00007fff3780b908 _CF_forwarding_prep_0 + 120 5 libtk8.6.dylib
0x000000010fd051f2 TkpInit + 408 6 libtk8.6.dylib
0x000000010fc74aac Initialize + 2454 7
_tkinter.cpython-38-darwin.so 0x000000010fac8714 Tcl_AppInit + 84 8 _tkinter.cpython-38-darwin.so 0x000000010fac8032
_tkinter_create + 1362 9 Python 0x000000010f790e8f cfunction_vectorcall_FASTCALL + 175 10 Python
0x000000010f822c4c call_function + 444 11 Python
0x000000010f81faae _PyEval_EvalFrameDefault + 25678 12 Python
0x000000010f823a94 _PyEval_EvalCodeWithName + 2804 13 Python
0x000000010f75504e _PyFunction_Vectorcall + 270 14 Python
0x000000010f7543b7 _PyObject_FastCallDict + 247 15 Python
0x000000010f7559bf _PyObject_Call_Prepend + 143 16 Python
0x000000010f7abb21 slot_tp_init + 145 17 Python
0x000000010f7a6ff9 type_call + 297 18 Python
0x000000010f754565 _PyObject_MakeTpCall + 373 19 Python
0x000000010f822ca5 call_function + 533 20 Python
0x000000010f81faae _PyEval_EvalFrameDefault + 25678 21 Python
0x000000010f823a94 _PyEval_EvalCodeWithName + 2804 22 Python
0x000000010f819584 PyEval_EvalCode + 100 23 Python
0x000000010f8690f0 PyRun_FileExFlags + 336 24 Python
0x000000010f8687e0 PyRun_SimpleFileExFlags + 864 25 Python
0x000000010f885c6f Py_RunMain + 2159 26 Python
0x000000010f885faf pymain_main + 223 27 Python
0x000000010f8861ab Py_BytesMain + 43 28 libdyld.dylib
0x00007fff718d9cc9 start + 1 29 ???
0x0000000000000002 0x0 + 2 ) libc++abi.dylib: terminating with
uncaught exception of type NSException Abort trap: 6
The script ran perfectly when being called from the command line on a Windows computer but for whatever reason I cant get it to run from the command line on my mac, but yet it works in the IDE...
I'll include the code below. I would appreciate any help I can get and if you need more information just ask
import tkinter as tk
import youtube_dl
from moviepy.editor import *
import shutil
BG = "#191970"
# midnight blue #191970
main_window = tk.Tk()
main_window.title("Video Scraper")
main_window.geometry("850x690")
main_window.config(bg=BG)
frame = tk.Frame(main_window, bg="white")
frame.place(relx="0.1", rely="0.05", relwidth=0.8, relheight=0.9)
title = tk.Label(frame, text="Video Scraper")
title.config(font=("Verdana", 44))
title.pack(fill="x")
label = tk.Label(frame, text="Please enter the url(s) of the videos you would like to download so that there's "
"only 1 link per line\nAlso note that there can't be any spaces at the beginning or "
"end of the line", bg="pink")
label.pack()
text_area = tk.Text(frame, bg="#BBFFFF")
text_area.pack(fill="y", expand=True)
frame2 = tk.Frame(main_window, bg=BG)
frame2.place(relx="0.2", rely="0.95", relwidth=0.6, relheight=0.05)
var = tk.IntVar()
var.set(2)
def set_var1():
var.set(1)
def set_var2():
var.set(2)
audio_only = tk.Radiobutton(frame2, text=".mp3", variable="var", value=1, command=set_var1)
vid_and_aud = tk.Radiobutton(frame2, text=".mp4", variable="var", value=2, command=set_var2)
audio_only.pack(side="left")
vid_and_aud.pack(side="left")
def get_text():
text = text_area.get("1.0", "end-1c")
broken_text = text.split("\n")
links = []
for item in broken_text:
link = [item]
links.append(link)
audio_only.config(state="disabled")
vid_and_aud.config(state="disabled")
download_btn.config(state="disabled")
download_videos(links, var.get())
def download_videos(url_links, download_format):
counter = 0
vid_info = []
print(url_links)
print(download_format)
# Get video data for each link and put it into a list
with youtube_dl.YoutubeDL() as ydl:
for link in url_links:
meta = ydl.extract_info(link[0], download=False)
vid_info.append(meta)
ydl_opts = {
'format': 'mp4',
'outtmpl': '%(title)s.mp4',
'quiet': True,
'noplaylist': True
}
while counter < len(url_links):
filename = vid_info[counter]['title'] + ".mp4"
print("\n\nDownloading --> " + filename)
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(url_links[counter])
print("Video Successfully Downloaded!")
if download_format == 1:
print("Converting Video(.mp4) to Audio(.mp3)...")
video = VideoFileClip(filename)
audio_file = filename.replace("mp4", "mp3")
video.audio.write_audiofile(audio_file, logger=None)
video.close()
print("Video Successfully Converted!")
print("Cleaning up...")
# remove video file
print("--> Removing Video(.mp4) File")
os.remove(filename)
# move audio
print("--> Moving Audio to Audio(mp3) Folder")
shutil.move(audio_file, "Audio(mp3)")
print("--> Done")
print("Completed " + str(counter + 1) + "/" + str(len(url_links)))
else:
shutil.move(filename, "Video(mp4)")
print("Completed " + str(counter + 1) + "/" + str(len(url_links)))
counter += 1
download_btn = tk.Button(frame2, text="Download!", command=get_text)
download_btn.pack(side="right")
main_window.mainloop()

Selenium return empty images after few images

I am working with selenium and I want to get to images. The problem is that the selenium works up to 21 images and after that, it returns empty URLs like below.
1 : https://photo.venus.com/im/19230307.jpg?preset=dept
2 : https://photo.venus.com/im/18097354.jpg?preset=dept
3 : https://photo.venus.com/im/19230311.jpg?preset=dept
4 : https://photo.venus.com/im/19234200.jpg?preset=dept
5 : https://photo.venus.com/im/17307902.jpg?preset=dept
6 : https://photo.venus.com/im/19305650.jpg?preset=dept
7 : https://photo.venus.com/im/19060456.jpg?preset=dept
8 : https://photo.venus.com/im/18295767.jpg?preset=dept
9 : https://photo.venus.com/im/19102600.jpg?preset=dept
10 : https://photo.venus.com/im/19230297.jpg?preset=dept
11 : https://photo.venus.com/im/16181113.jpg?preset=dept
12 : https://photo.venus.com/im/19101047.jpg?preset=dept
13 : https://photo.venus.com/im/19150290.jpg?preset=dept
14 : https://photo.venus.com/im/19042244.jpg?preset=dept
15 : https://photo.venus.com/im/19230329.jpg?preset=dept
16 : https://photo.venus.com/im/19101040.jpg?preset=dept
17 : https://photo.venus.com/im/17000870.jpg?preset=dept
18 : https://photo.venus.com/im/19100952.jpg?preset=dept
19 : https://photo.venus.com/im/19183658.jpg?preset=dept
20 : https://photo.venus.com/im/19102243.jpg?preset=dept
21 : https://photo.venus.com/im/18176590.jpg?preset=dept
22 : data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC
23 : data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC
24 : data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC
25 : data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC
26 : ...
I even used time sleep, but it has not worked. Any ideas would be appreciated.
Here is also my code:
url = 'https://www.venus.com/products.aspx?BRANCH=7~63~'
driver.get(url)
product_container_ls = driver.find_elements_by_class_name('product-container')
for prd in product_container_ls:
# Finding elements of images by class name
image_lm = prd.find_element_by_class_name('main')
# The url to image
image_url = image_lm.get_attribute('src')
print(image_id, ': ', image_url)
# Image Path
image_path = os.path.join(directory, f'{image_name}.jpg')
# Getting and saving the image
urllib.request.urlretrieve(image_url, image_path)
image_id += 1
time.sleep(3)
driver.quit()
Thanks!
Look for the attribute of data-original rather than the src since this how they are lazy loading the images. I modified the following variable and got all the images
image_url = image_lm.get_attribute('data-original')
Here is a sample of my print out for that variable:
https://photo.venus.com/im/18235739.jpg?preset=dept
https://photo.venus.com/im/19034244.jpg?preset=dept
https://photo.venus.com/im/17199949.jpg?preset=dept
https://photo.venus.com/im/19121197.jpg?preset=dept
https://photo.venus.com/im/18235918.jpg?preset=dept
https://photo.venus.com/im/18366410.jpg?preset=dept

Where do these spaces come from and how can I get rid of them?

beginner here. Learning Python through a book called "Breaking Ciphers with Python". As a part of a simple encryption program, I wrote this (this is only the beginning):
import pyperclip
fg = lambda text, color: "\33[38;5;" + str(color) + "m" + text + "\33[0m"
bg = lambda text, color: "\33[48;5;" + str(color) + "m" + text + "\33[0m"
# Simple usage: print(fg("text", 160))
msg = input('\n\nEnter your secret:\n\n')
msg_len_int = len(msg)
msg_len_str = str(len(msg))
print('\n\nChoose key (has to be less than', fg((msg_len_str), 40), '): ')
key = input('\n\nChoose your here: ')
As an output I get this:
I can't understand why I have 2 space chars I did not put, one before and the other after fg((msg_len_str), 40).
The Python documentation says:
All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end.
To get rid of the spaces, you can set sep to an empty string:
print('\n\nChoose key (has to be less than', fg((msg_len_str), 40), '): ', sep='')

Not sure why my python output is looping

I wrote a little bit of code to read a number in a file. Append it to a variable, then increment the number so the next time it runs the number in the file will be number +1. It looks like its working except it seems to increment twice.. For example here is my code :
11 def mcIPNumber():
12 with open('mcIPlatest.txt', 'r+') as file:
13 NameNumber= file.read().replace('\n','')
14 NameNumber=int(NameNumber)
15 NewNumber= NameNumber+1
16 print "newnumber = %s" % NewNumber
17 file.seek(0)
18 file.write(str(NewNumber))
19 file.truncate()
20 return NameNumber
21
22 def makeNameMCTag():
23 NameNumber = mcIPNumber()
24 NameTag = "varName" + str(NameNumber)
25 print "Name Tag: %s" % NameTag
26 mcGroup = "varTagmc"
27 #IPNumber = 1
28 mcIP = "172.16.0.%s" % NameNumber
29 print ( "Multicast Tag: %s, %s" % (mcGroup,mcIP))
30
31
32 mcIPNumber()
33 makeNameMCTag()
But here is my output.. notice that "NewNumber" gets printed out twice.. for some reason"
newnumber = 2
newnumber = 3
Name Tag: varName2
Multicast Tag: varTagmc, 172.16.0.2
So it correctly made my varName2 and my IP 172.16.0.2 (incremented my initial number in the file by 1) but this means the 2nd time I run it.. I get this:
newnumber = 4
newnumber = 5
Name Tag: varName
Multicast Tag: varTagmc, 172.16.0.4
My expected result is this:
newnumber = 3
Name Tag: varName3
Multicast Tag: varTagmc, 172.16.0.3
Any idea why its looping?
Thanks!
(by the way if you're curious I'm trying to write some code which will eventually write the tf file for my TerraForm lab)
Because of this:
def makeNameMCTag():
NameNumber = mcIPNumber()
You are calling mcIPNumber from inside makeNameMCTag, so you don't excplicitly need to call that method in line 32.
Alternatively
def make_name_mc_tag(name_number):
NameTag = "varName" + str(name_number)
print "Name Tag: %s" % NameTag
...
make_name_mc_tag(mcIPNumber())
here you are passing the required data as a parameter.

for loop to insert things into a tkinter window

I have Tkinter program that has to add a significant amount of data to the window so I tried to write a for loop to take care of it but since I have to use a string variable for the name of the object that Tkinter is running .insert() on the object. I didn't explain it very well here is the method
def fillWindow(self):
global fileDirectory
location = os.path.join(fileDirectory, family + '.txt')
file = open(location, 'r')
ordersDict = {}
for line in file:
(key, value) = line.split(':', 1)
ordersDict[key] = value
for key in ordersDict:
ordersDict[key] = ordersDict[key][:-2]
for item in ordersDict:
if item[0] == '#':
if item[1] == 'o':
name = 'ordered%s' %item[2:]
right here is the problem line because I have the variable that matches the name of the entry object already created but 'name' is actually a string variable so it gives me the error "AttributeError: 'str' object has no attribute 'insert'"
name.insert(0,ordersDict[item])
here is the entire class. It makes a Tkinter window and fills it with a sort of shipping screen so all the entries are for how many orders of a certain thing are needed. I'm also very new so I know that I do things the long way a lot.
class EditShippingWindow(Tkinter.Toplevel):
def __init__(self, student):
Tkinter.Toplevel.__init__(self)
self.title('Orders')
family = student
## Window Filling
ageGroupLabel = Tkinter.Label(self,text='Age Group')
ageGroupLabel.grid(row=0,column=0)
itemColumnLabel = Tkinter.Label(self,text='Item')
itemColumnLabel.grid(row=0, column=1)
costColumnLabel = Tkinter.Label(self,text='Cost')
costColumnLabel.grid(row=0, column=2)
orderedColumnLabel = Tkinter.Label(self,text='Ordered')
orderedColumnLabel.grid(row=0, column=3)
paidColumnLabel = Tkinter.Label(self,text='Paid')
paidColumnLabel.grid(row=0, column=4)
receivedColumnLabel = Tkinter.Label(self,text='Received')
receivedColumnLabel.grid(row=0, column=5)
#Item Filling
column1list = ['T-Shirt (2T):$9.00', 'T-Shirt (3T):$9.00', 'T-Shirt (4T):$9.00',
'Praise Music CD:$10.00', ':', 'Vest L(Size 6):$10.00', 'Vest XL(Size 8):$10.00',
'Hand Book (KJ/NIV):$8.75', 'Handbook Bag:$6.00', 'Memory CD (KJ/NIV):$10.00',
':', 'Vest L(size 10):$10.00', 'Vest XL(Size 12):$10.00', 'Hand Glider (KJ/NIV/NKJ):$10.00',
'Wing Runner (KJ/NIV/NKJ):$10.00', 'Sky Stormer (KJ/NIV/NKJ):$10.00', 'Handbook Bag:$5.00',
'Memory CD (S/H/C):$10.00', 'Hand Glider Freq. Flyer:$8.00', 'Wing Runner Freq. Flyer:$8.00',
'Sky Stormer Handbook:$8.00' , ':', 'Uniform T-Shirt Size (10/12/14):$13.00',
'Uniform T-Shirt Size(10/12/14):$13.00', 'Uniform T-Shirt(Adult S / M / L / XL):$13.00',
'3rd & 4th Gr. Book 1 (KJ / NIV / NKJ):$8.75', '3rd & 4th Gr. Book 2 (KJ / NIV / NKJ):$8.75',
'4th & 5th Gr. Book 1 (KJ / NIV / NKJ):$8.75', '4th & 5th Gr. Book 2 (KJ / NIV / NKJ):$8.75',
'Memory CD 3rd & 4th Gr. Book (1/2):$10.00', 'Drawstring Backpack:$5.50']
column1num = 1
for item in column1list:
num = str(column1num)
(title, price) = item.split(':')
objectName1 = 'column1row' + num
objectName1 = Tkinter.Label(self,text=title)
objectName1.grid(row=column1num, column=1)
objectName2 = 'column1row' + num
objectName2 = Tkinter.Label(self,text=price)
objectName2.grid(row=column1num, column=2)
column1num += 1
#Ordered Paid Recieved Filler
for i in range(32):
if i == 11 or i == 22 or i == 0 or i == 5:
pass
else:
width = 10
# First Column
title1 = 'ordered' + str(i)
self.title1 = Tkinter.Entry(self,width=width)
self.title1.grid(row=i,column=3)
#self.title1.insert(0, title1)
#Second
title2 = 'paid' + str(i)
self.title2 = Tkinter.Entry(self,width=width)
self.title2.grid(row=i,column=4)
#self.title2.insert(0, title2)
#Third
title3 = 'received' + str(i)
self.title3 = Tkinter.Entry(self,width=width)
self.title3.grid(row=i,column=5)
#self.title3.insert(0, title3)
## Methods
def fillWindow(self):
global fileDirectory
location = os.path.join(fileDirectory, family + '.txt')
file = open(location, 'r')
ordersDict = {}
for line in file:
(key, value) = line.split(':', 1)
ordersDict[key] = value
for key in ordersDict:
ordersDict[key] = ordersDict[key][:-2]
for item in ordersDict:
if item[0] == '#':
if item[1] == 'o':
self.name = 'ordered%s' %item[2:]
self.name.insert(0,ordersDict[item])
fillWindow(self)
It looks like you have a conceptual error there: inside this method, the variable "name" does not exist up to the last line on the first listing. Then it is created, and points to an ordinary Python string -- if you are using a "name" variable elsewhere on your class that variable does not exist inside this method.
For an easy fix of your existing code, try calling the variable as "self.name" instead of just name where it is created, and on your last line in this method use:
self.name.insert(0,ordersDict[item]) instead.
The self. prefix will turn your variable into an instance variable, which is shared across methods on the same instance of the class.
On a side note, you don' t need even the dictionary much less three consecutive for loops on this method, just insert the relevant values you extract from "line" in your text variable.

Categories

Resources