Load R package from character string - string

I want to create a function which includes loading a package that I make within the function. A short example (which doesn't run!):
loadMe <- function(name){
genLib(xxx, libName = name) #make a new library with name "name"
library(name) #load the new library...
}
This does not work! A bit of reproducible code which illustrates my main problem:
library(ggplot) #this works fine
load.this <- "ggplot"
library(load.this) #I want this to load ggplot!
I know the problem is that library() and require() take as an argument an object name which does not exist yet. I have tried wrapping my character string with parse(), deparse(), substitute(), expression(), quote(), etc etc. These all return the same problem:
library(load.this)
# Error in library(loadss) : there is no package called 'loadss'
library(deparse(load.this))
# Error in library(deparse(loadss)) : 'package' must be of length 1
Is there a way to do this?

Use the character.only argument
foo <- "ggplot2"
library(foo,character.only=TRUE)

You say that you have tried using parse(). The following seems to work for me:
eval(parse(text = 'library(MASS)')[1])

Related

exec() not working when trying to execute a string containing the command "abs.__doc__"

I am trying to execute the command abs.__ doc__ inside the exec() function but for some reason it does not work.
function = input("Please enter the name of a function: ")
proper_string = str(function) + "." + "__doc__"
exec(proper_string)
Essentially, I am going through a series of exercises and one of them asks to provide a short description of the entered function using the __ doc__ attribute. I am trying with abs.__ doc__ but my command line comes empty. When I run python in the command line and type in abs.__ doc__ without anything else it works, but for some reason when I try to input it as a string into the exec() command I can't get any output. Any help would be greatly appreciated. (I have deliberately added spaces in this description concerning the attribute I am trying to use because I get bold type without any of the underscores showing.)
As a note, I do not think I have imported any libraries that could interfere, but these are the libraries that I have imported so far:
import sys
import datetime
from math import pi
My Python version is Python 3.10.4. My operating system is Windows 10.
abs.__doc__ is a string. You should use eval instead of exec to get the string.
Example:
function = input("Please enter the name of a function: ")
proper_string = str(function) + "." + "__doc__"
doc = eval(proper_string)
You can access it using globals():
def func():
"""Func"""
pass
mine = input("Please enter the name of a function: ")
print(globals()[mine].__doc__)
globals() return a dictionary that keeps track of all the module-level definitions. globals()[mine] is just trying to lookup for the name stored in mine; which is a function object if you assign mine to "func".
As for abs and int -- since these are builtins -- you can look it up directly using getattr(abs, "__doc__") or a more explicit: getattr(__builtins__, "abs").__doc__.
There are different ways to lookup for a python object corresponding to a given string; it's better not to use exec and eval unless really needed.

value is not updated in python using self.counter

enter image description here
Above code displays output as 10 10 but i used change_counter to update counter value to 11. why is it not updating
Can someone help me plz
The problem is, that you are accessing a static variable.
When you write:
print(demo.counter)
it will always print the number 10, because it is defined this way in the demo-class.
If you want the value to be changed after calling obs.change_counter() you need to access the value of the object "obj" not the class demo.
Another mistake you have made is that you never actually call obj.change_counter, because you forgot the brackets for the function call. The statement obj.change_counter does not throw an error in python but it also wont have any effect.
So instead of this:
obj = demo()
print(demo.counter)
obj.change_counter
print(demo.counter)
You have to do this:
obj = demo()
print(obj.counter) # <- notice the reference to the object
obj.change_counter() # <- notice the brackets
print(obj.counter)

Set/Modify the variable used in a function from imported module

Consider following code:
##testing.py
namespace = "original"
def print_namespace():
print ("Namespace is", namespace)
def get_namespace_length(_str = namespace):
print(len(_str))
##Main
import testing
testing.namespace = "test"
testing.printnamespace()
testing.get_namespace_length()
print_namespace() return 'test' as exepcted, but the get_namespace_length() still return 8 which is the length of 'original'. How can I make get_namespace_length() taking the modified variable?
The use case of such implementation is some functions are used the same variable in the imported module, if I can modify/set variable, I can avoid explicitly to call out new variable in each function. Can someone advise?
Also, it doesn't have to be implemented in the way shown above, as long as it works. (global variable etc.)
Um... your default argument for get_namespace_length is database, undefined in your code snippet, also you switch from calling testing to test (I'm guessing that was one of many typos).
In short though, I believe its to do with how the bytecode is compiled in python. Arguments are 'preloaded', and therefore a change to a variable (such as namespace) does not get included in the compilation of get_namespace_length. If I remember correctly, upon import the entire code of the imported file is compiled and executed (try putting a print() statement at the end of testing.py to see)
So what you really want to do to obtain your length of 4 is change testing.py to:
namespace = "original"
def print_namespace():
print ("Namespace is", namespace)
def get_namespace_length():
_str = namespace
print(len(_str))
Or just print(len(namespace)).
Hope that helps!

How can I make objects with functions? (Turning a string into a object name)

I've just started learning Python recently and the first project I'm making is a text based adventure game however I've run into a problem. I need a function that makes more objects using the class Goblin that are named after a string.
def spawn(name):
title = name
exec("{0} = {1}".format('title', Goblin))
return title, 'spawn'
Essentially, another function calls this function to create another Goblin (a class) using the input name(a string) as the name of the new Goblin.
What I don't under stand though is that when I run the code(using "bill" as the argument), it gives me this error.
bill = <class '__main__.Goblin'>
^
SyntaxError: invalid syntax
Shouldn't my function be equivalent to:
bill = Goblin
When you do this:
exec("{0} = {1}".format('title', Goblin))
format method converts Goblin class by calling default __str__ method which yields <class '__main__.Goblin'>
Do this instead:
exec("{0} = {1}".format('title', 'Goblin'))
Wait! don't to this, just do:
title = Goblin
as it's strictly equivalent (without any security issues :)).
But that will just alias Goblin class to title. No real interest to all this after all (unless you want to create an instance?: title = Goblin())
With your comment: "I want a Goblin that is named after the string which title represents" I get it: you need
exec("{0} = {1}".format(title, 'Goblin()'))
(no quotes for the first arg so the name you're passing is used, and () on the second to create an instance)
Again: this is really a clumsy way of doing it. What if you want to iterate through all your goblins?
It would be much better to create a dictionary:
goblins_dict = dict()
goblins_dict["my_goblin"] = Goblin()
goblins_dict["my_goblin_2"] = Goblin()
and so on...

QComboBox.currentText() -- PySide vs PyQt4

I've got a python script using PySide and it works fine.
But then I thought to check if it gonna work with PyQt4.
And after changing the import strings to PyQt4, things went wrong.
The error points to the subject, as follows:
File "./my_file.py", line 93, in showit
curr_query = '.'.join(curr_query)
TypeError: sequence item 0: expected string, QString found
From the docs I can see that PySide subject method returns 'unicode' string,
but the PyQt4 one returns QString object.
Playing with the str(), str() etc did not seem to do the job.
Here's the function code:
def showit(self, idx):
curr_query = []
for i in xrange(idx+1):
>> x = self.combo[i].currentText()
>> if x:
curr_query.append(x)
else:
break
curr_query = '.'.join(curr_query)
This reads text of a set of QCombobox'es to build up a dot-sepated string presentation that I use later.
The marked '>>' lines is where the issue occurs - the 'x' object is never an empty string, suddenly, as it was while using PySide library. But it is expected to be empty, if there's an empty self.combo[i] .
I've searched the SO archive and found this answer but not able to use it.
Please advice how to fix this.
You need to convert your x values to a string of sorts. Something like
curr_query.append(str(x))
should do the trick.

Resources