How to make the path to songs in pygame relative - python-3.x

Im working on a simple Snake game in python, and its working as intended here at home, but when I put the code on github, it doesn't find the path to the songs, I want to make this path relative, intead of absolute so it works on every computer.
Here is the part of the code for the song files -
def game_sound(s):
""" Include the game sfx and music"""
if s == 0:
pygame.mixer.music.load("background.ogg")
pygame.mixer.music.play(-1)
elif s == 1:
pygame.mixer.Sound("eating.wav").play()
elif s == 2:
pygame.mixer.Sound("game-over.wav").play()
TL - DR- It works here at home and nowhere else, Im trying to find a way to fix that by making the path relative I just dont know how. Can someone help?

Standard method is to find real path to folder with application
import os, sys
APP_FOLDER = os.path.dirname(os.path.realpath(sys.argv[0]))
And later use it to create real path to file
full_path = os.path.join(APP_FOLDER, "eating.wav")
pygame.mixer.Sound(full_path).play()
Or you have to change "current working directory" (CWD) to application folder.
os.chdir(APP_FOLDER)
pygame.mixer.Sound("eating.wav").play()
You can check current working directory with
print(os.getcwd())
BTW: without this method problem is not only when you run on different computer but also when you run from different folder on the same computer - so it makes problem when you create shortcut/icon on desktop which executes program as python game_folder/game.py

Related

Relative path code is giving me a different error for auto-py-to-exe

I am trying to convert my .py to .exe using auto-py-to-exe. I have two logos that I want on my file, and the first edition of the app worked with no issues, and the onefile option worked great. However, I have made updates to the app over the past month, and when I go to use onefile again, the program couldn't locate my logos. So, I pasted the relative path code below. Now I get an error which I have screenshotted. I have not the slightest clue how to fix this. If someone could give me some direction, that would be fantastic. Thank you!
IMAGE:
https://www.dropbox.com/s/zby2e8s45b9ovu6/Stack.PNG?dl=0
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp and stores path in MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")```

Beginner Python Project - My function is skipping, what is causing this?

as the title says I'm a beginner with Python. I have started to work on what I thought first was a simple enough script for scanning a folder and printing the names of each subdirectory to a CMD prompt.
However, I've run into an issue where the function in the code below does not execute. I suspect it's to do with Windows permissions which is why I've added in the is_admin(): function.
My question is, what is it that is causing the function to skip? and what is the proper way to achieve what it is I am trying to do?
Any and all help is appreciated and if anyone could point me in the direction for learning more about Python and the Windows OS technical side for programmers would be doing me a huge favor.
Thanks in advance :)
import os, sys, ctypes
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
rootdir = 'C:/Windows'
def listdirs(rootdir):
for file in os.listdir(rootdir):
d = os.path.join(rootdir, file)
if os.path.isdir(d):
print(d)
listdirs(d)
listdirs(rootdir)
else:
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv\[1:\]), None, 1)
input('Press any key to continue...')
Expecting the program to:
Produce an output of all the subdirectories of a folder printed to a CMD prompt window and have the window stay open when the program has finished executing each line of code. The Window should remain open until the user is finished with it. The Windows UAC should prompt asking the user if they wish to run as admin, if the user is already an admin then it should skip this and proceed to run the program.

requests.get(url).headers.get('content-disposition') returning NONE on PYTHON

Well, I've got the need of automate a process in my job(actually I'm an intern), and I just wondered if I could use Python for such process. I'm still processing my ideas of how to do those stuffs, and now I'm currently trying to understand how to download a file from a web URL using python3. I've found a guide on another website, but there's no active help there. I was told to use the module requests to download the actual file, and the module re to get the real file name.
The code was working fine, but then I tried to add some features like GUI, and it just stopped working. I took off the GUI code, and it didn't work again. Now I have no idea of what to do to get the code working, pls someone helo me, thanks :)
code:
import os
import re
# i have no idea of how this function works, but it gets the real file name
def getFilename(cd):
if not cd:
print("check 1")
return None
fname = re.findall('filename=(.+)', cd)
if len(fname) == 0:
print("check 2")
return None
return fname[0]
def download(url):
# get request
response = requests.get(url)
# get the real file name, cut off the quota and take the second element of the list(actual file name)
filename = getFilename(response.headers.get('content-disposition'))
print(filename)
# open in binary mode and write to file
#open(filename, "wb").write(response.content)
download("https://pixabay.com/get/57e9d14b4957a414f6da8c7dda353678153fd9e75b50704b_1280.png?attachment=")
os.system("pause")```

I need to copy files from appdata/local to C drive and overwrite them each time the program is run

I use a program which, sadly corrupts some saved files at random times. To be helpful (although I am a novice at this) I am trying to make a Python program to basically backup those file from the AppData/local directory and put them in a folder on C. I need this program to overwrite the previously copied files each time it is run.
I need to generalize the AppData/local because each person who uses this program would, in theory, have a different user directory preceding the AppData folder.
I've tried running some of my own attempts at a solution.
I will post the results.
# Imports
import shutil
import os
import distutils
from distutils import dir_util
# Paths
# os.makedirs("C:/RevSaves-Backup")
path = '%LOCALAPPDATA%/Remnant'
backup_path = "C:/RevSaves-Backup"
# Procedures
print("The Very Basic Remnant Save Backup Utility")
print(" ")
print("Backing up the save source:")
print(path)
print(" ")
print("It is recommended you run this at regular intervals \nto ensure you have the latest saves up to date.")
distutils.dir_util.copy_tree(path, backup_path)
print("Backup completed.")
When I execute this via command prompt or PowerShell, I get the following message:
Traceback (most recent call last):
File "RevSaveBkUp.py", line 28, in
distutils.dir_util.copy_tree(path, backup_path)
File "C:\Users\candr\AppData\Local\Programs\Python\Python37-32\lib\distutils\dir_util.py", line 124, in copy_tree
"cannot copy tree '%s': not a directory" % src)
distutils.errors.DistutilsFileError: cannot copy tree '%LOCALAPPDATA%/Remnant': not a directory
I am having trouble "targeting" the system-specific local AppData folder.
After a lot of reading, I made the following solution if anyone else is trying to do something similar. I do not know if this is the "best" or "right" way of doing things, however.
Here is how I targeted the AppData Local folder regardless of the user logged in:
path = os.path.join(os.path.expanduser('~'), 'AppData', 'Local')
Some explanations for anyone who is new like me:
os.path.join basically connects folders together in the path. For example, using the above code, join would "connect" AppData to Local and the "User Folder" (referenced in the code as '~'). The output would look like this: C:\Users\your_username\AppData\Local
os.path.expanduser defines the user in question. For example, "~" targets the current user logged in. It goes inside the () because this is how you tell "your code" who, to target. If you wanted a specific user (if you had more than one) you could possibly use os.path.expanduser('Jane') I believe.
Keeping the notes above in reference, this method allowed me to define the variables I needed to and use them for the copy above, where I could not normally use the AppData directory as I wanted.
This was done by using the following code as an example:
path = os.path.join(os.path.expanduser('~'), 'AppData', 'Local')
backup_path = "C:/MyBackupFolder"
Finally we executed the copy with this:
distutils.dir_util.copy_tree(path, backup_path)
The above copied The AppData information I needed to the backup folder.
I hope this helps everyone learn as I did, it came in quite handy.

Write to %temp% with python?

I have a small program that works fine on my PC but I want to make it portable. What it does is download an image from the internet, set as desktop background, wait one minute and update the image. I know that I cannot write directly to folders like appdata, as I do not know the username of the person using the computer. I need to save the downloaded image somewhere, so I would save it in the windows Temp folder.
Some options I think would be to (However I don't know how to do this in python)
Use something like %temp% to access the folder.
Find out the username of the person running the program and insert into path
Use a variable for the username.
Use relative paths
I would like to try and not have to use another module not by default included in Python 3, as I want to cx_freeze it later on.
import pythoncom
from urllib import request
from win32com.shell import shell, shellcon
from time import sleep
def get_image():
f = open('C:\\Users\\MyUser\\Desktop\\Python\\bg\\bg.jpg', 'wb') #Open old image
f.write(request.urlopen('blalbla.com/foo/img.jpg').read()) #Get new image and write
f.close()
pathtoimg = 'C:\\Users\\MyUser\\Desktop\\Python\\bg\\bg.jpg'
count = 0
while 1:
get_image()
iad = pythoncom.CoCreateInstance(shell.CLSID_ActiveDesktop, None,
pythoncom.CLSCTX_INPROC_SERVER, shell.IID_IActiveDesktop)
iad.SetWallpaper(pathtoimg, 0)
iad.ApplyChanges(shellcon.AD_APPLY_ALL)
count += 1
print(count)
sleep(60)
Use this to locate Temp:
import os
mytmpdir = os.environ['TEMP'] #Must be uppercase

Resources