import class with pandas from file - importerror

I have two files:
main.py
from personal_function.Convert import cls_Convert
df_key = 'PERFIL'
a = cls_Convert(df_data_2)
a.convert_cat_to_num(df_key)
df_data_2 = a.df
personal_function/Convert.py
import pandas as pd
class cls_Convert:
def __init__(self,df):
self.df = df
# Mudar variavel categorica para numerica
def convert_cat_to_num(self,df_key):
self.df[df_key] = pd.factorize(self.df[df_key],sort=True)[0] + 1
return self.df
# Mudar variavel numerica para categorica
def convert_num_to_cat(self,df_key,cat_bin,cat_label):
self.df[df_key].replace(to_replace = cat_bin, value =cat_label, inplace=True)
return self.df
however I get this error
ImportError: cannot import name 'cls_Convert' from 'personal_function.Convert'

For a class or function to be visible outside of a package, it must be imported in the package's __init__.py file which is run when the package is imported from somewhere. All the variables, imports, method, and classes defined in that __init__.py are then made visible to the package that was importing them. Take the below example:
example/example.py
def visible():
pass
def not_visible():
pass
example/init.py
from .ex import visible
main.py
from example import visible
from example import not_visible # results in an error since it was not imported
# in the `example` package's `__init__.py` file.
To make your Convert class visible to the external main.py file, create the __init__.py for the package.
You can read more about python submoduling here

I need to use
from os import getcwd
from sys import path
cwd = getcwd()
path.append(cwd)
than use the whole absolute path

Related

os.execl do not operating with classes

for the code below, execl destroy the script but not restart. If the method is out of the class is working. What I am doing wrong.?
import os
import sys
from tkinter import *
class parent():
def __init__(self,root):
self.root=root
def show_root(self):
self.root=Tk()
a=Button(self.root,text='restart',command=self.restart)
a.grid()
def restart(self):
sys.stdout.flush()
os.execl(sys.executable, 'python', __file__, *sys.argv[1:])
return
if __name__=='__main__':
gr=parent(None)
gr.show_root()

pytest - mockup a complex module import

I have found several posts on how to "hide" a package and simulate an ImportError with pytest, however, I haven't succeeded in my case and I am looking for some help:
Test for import of optional dependencies in __init__.py with pytest: Python 3.5 /3.6 differs in behaviour
Test behavior of code if optional module is not installed
and related
Here is the content of an __about__.py file that I want to test with pytest.
"""Get the metadata from the package or from setup.py."""
try:
import importlib
metadata = importlib.metadata
except ImportError:
import importlib_metadata as metadata
try:
data = metadata.metadata("mypackage")
__version__ = data["Version"]
__author__ = data["Author"]
__name__ = data["Name"]
except metadata.PackageNotFoundError:
# The repo of the package is accessible to python to get at least the version
import re
from pathlib import Path
try:
from nested_grid_plotter import __file__ as loc
with open(Path(loc).parent.joinpath("../setup.py"), "r") as f:
data = f.read()
except FileNotFoundError:
data = ""
def version_parser(v):
"""Parse the version from the setup file."""
version_pattern = (
r"""(version\s*=\s*)["|'](\d+(=?\.(\d+(=?\.(\d+)*)*)*)*)["|']"""
)
regex_matcher = re.compile(version_pattern).search(v)
if regex_matcher is None:
return "unknwon"
return regex_matcher.group(2)
try:
__version__ = version_parser(data)
except Exception:
__version__ = "unknown"
__author__ = "unknown"
__name__ = "unknown"
Here is the __init__.py at the root of the package:
from .__about__ import __version__, __name__, __author__
And here is the tests that I have come up with until now. However, I am not able to hide importlib.
"""Test the file __about__.py."""
import pytest
import sys
class PackageDiscarder:
def __init__(self):
self.pkgnames = []
def find_spec(self, fullname, path, target=None):
if fullname in self.pkgnames:
raise ImportError()
#pytest.fixture
def no_requests():
sys.modules.pop("importlib", None)
d = PackageDiscarder()
d.pkgnames.append("importlib")
sys.meta_path.insert(0, d)
yield
sys.meta_path.remove(d)
#pytest.fixture(autouse=True)
def cleanup_imports():
yield
sys.modules.pop("mypackage", None)
def test_requests_available():
import mypackage
assert mypackage.__version__ != "unknwon"
#pytest.mark.usefixtures("no_requests")
def test_requests_missing():
import mypackage
assert mypackage.__version__ != "unknwon"
Here is the coverage report:
Name Stmts Miss Cover Missing
----------------------------------------------------------------
mypackage/__about__.py 31 10 68% 5-6, 10-12, 23-24, 33, 38-39
----------------------------------------------------------------
TOTAL 31 10 68%

Unable to use pytest parameterize functionality to update the YAML config

I am using ruamel.yaml module to update the YAML using python.
I wanted to use pytest parameterize functionality to update the YAML config.
Here is the test.yaml file:
TestConfig:
hostname: 10.2.4.6
Organisation:
Employee:
Name: Smriti
Skilss: Python
OrganizationName: ABC
UserId: smriti_test#gmail.com
Here is the conftest file so that we need to not to explicitly import the fixture functionality:
from ruamel.yaml import YAML
import pytest
#pytest.fixture(scope='function')
def yaml_loader(request):
yaml = YAML()
file_path = 'test.yaml'
with open(file_path) as fp:
data = yaml.load(fp)
test = data['TestConfig']
x = request.param
print(x)
with open(file_path, "w") as file:
yaml.dump(data, file)
print(data)
Here is the implementation of sample testfile for running the test and using the fixture from conftest and update the config in YAML and perform the test.
import pytest
class TestYAML:
""" TestYAML """
#pytest.mark.parametrize("yaml_loader",[("test['Organisation']['Employee']\
['Name']='Arushi'")],indirect=True)
#pytest.mark.usefixtures("yaml_loader")
def test_update_yamlconfig(self):
pass
In the result I am seeing the x is printing the updated Value of Name to Arushi but in the YAML file the config is not updating.
After couple of tries i am able to find the solution to this question.
So Here is the updated code for reference:-
For test file i have taken two different param and i will assign that param individually when i call the fixtures and this has worked
test_yaml.py
import pytest
class TestYAML:
""" TestYAML """
#pytest.mark.parametrize("yaml_loader",
[("hostname","10.5.6.8")],indirect=True)
#pytest.mark.usefixtures("yaml_loader")
def test_update_yamlconfig(self):
pass
Here is the updated conftest where i have defined the fixture:-
from ruamel.yaml import YAML
import pytest
#pytest.fixture(scope='function')
def yaml_loader(request):
yaml = YAML()
file_path = 'test.yaml'
file_path1 = 'my.yaml'
with open(file_path) as fp:
data = yaml.load(fp)
test = data['TestConfig']
test[request.param[0]] = request.param[1]
with open(file_path1, "w") as file:
yaml.dump(data, file)
print(data)
And you will get the output as :-
platform linux -- Python 3.8.0, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 --
/mnt/c/Users/smaheshw/PycharmProjects/YAML/venv/bin/python3.8
cachedir: .pytest_cache
rootdir: /mnt/c/Users/smaheshw/PycharmProjects/YAML
collected 1 item
test_yaml.py::TestYAML::test_update_yamlconfig[yaml_loader0] Request parameters
hostname
ordereddict([('TestConfig', ordereddict([('hostname', '10.5.6.8'), ('Organisation',
ordereddict([('Employee', ordereddict([('Name', 'Smriti'), ('Skilss', 'Python'),
('OrganizationName', 'A
BC'), ('UserId', 'smriti_test#gmail.com')]))]))]))])
PASSED
If you are stuck with pytest not behaving as you want, you should take a step back and make sure
your yaml_laoder() function does what you expect:
import sys
from pathlib import Path
from ruamel.yaml import YAML
yaml_str = """\
TestConfig:
hostname: 10.2.4.6
Organisation:
Employee:
Name: Smriti
Skilss: Python
OrganizationName: ABC
UserId: smriti_test#gmail.com
"""
Path('test.yaml').write_text(yaml_str) # write out the file so that it is fresh every time
class R: pass
r = R()
r.param = "XXXXXX"
def yaml_loader(request):
yaml = YAML()
file_path = 'test.yaml'
with open(file_path) as fp:
data = yaml.load(fp)
test = data['TestConfig']
x = request.param
print(x)
with open(file_path, "w") as file:
yaml.dump(data, file)
print(data)
yaml_loader(r)
print('\n######### YAML #########\n')
print(Path('test.yaml').read_text())
which gives:
XXXXXX
ordereddict([('TestConfig', ordereddict([('hostname', '10.2.4.6'), ('Organisation', ordereddict([('Employee', ordereddict([('Name', 'Smriti'), ('Skilss', 'Python'), ('OrganizationName', 'ABC'), ('UserId', 'smriti_test#gmail.com')]))]))]))])
######### YAML #########
TestConfig:
hostname: 10.2.4.6
Organisation:
Employee:
Name: Smriti
Skilss: Python
OrganizationName: ABC
UserId: smriti_test#gmail.com
As you can clearly sea from the YAML content, it never gets updated with XXXXXX. This is because you don't assign to data
before writing out the test.yaml file.
Fix that first and then inject the code into your test.

Autofix directory structure based on package in scala

I have a file src/main/scala/foo.scala which needs to be inside package bar. Ideally the file should be inside src/main/scala/bar/foo.scala.
// src/main/scala/foo.scala
package bar
// ...
How can I auto-fix this issue throughout my project such that the folder structure matches the package structure?
Is there any SBT plugin etc that can help me fix this issue?
As far as I am aware there are not such tools, though AFAIR IntelliJ can warn about package-directory mismatch.
Best I can think if is custom scalafix (https://scalacenter.github.io/scalafix/) rule - scalafix/scalameta would be used to check file's actual package, translate it to an expected directory and if they differ, move file.
I suggest scalafix/scalameta because there are corner cases like:
you are allowed to write your packages like:
package a
package b
package c
and it almost like package a.b.c except that it automatically imports everything from a and b
you can have package object in your file and then if you have
package a.b
package object c
this file should be in a/b/c directory
so I would prefer to check if file didn't fall under any of those using some existing tooling.
If you are certain that you don't have such cases (I wouldn't without checking) you could:
match the first line with regexp (^package (.*))
translate a.b.c into a/b/c (matched.split('.').map(_.trim).mkString(File.separator))
compare generated location to an actual location ( I suggest resolving absolute file locations)
move file if necessary
If there is a possibility of having more complex case than that, I could replace first step by querying scalafix/scalameta utilities.
Here is an sbt plugin providing packageStructureToDirectoryStructure task that reads package statements from source files, creates corresponding directories, and then moves files to them
import sbt._
import sbt.Keys._
import better.files._
object PackagesToDirectories extends AutoPlugin {
object autoImport {
val packageStructureToDirectoryStructure = taskKey[Unit]("Make directory structure match package structure")
}
import autoImport._
override def trigger = allRequirements
override lazy val projectSettings = Seq(
packageStructureToDirectoryStructure := {
val log = streams.value.log
log.info(s"Refactoring directory structure to match package structure...")
val sourceFiles = (Compile / sources).value
val sourceBase = (Compile / scalaSource).value
def packageStructure(lines: Traversable[String]): String = {
val packageObjectRegex = """package object\s(.+)\s\{""".r
val packageNestingRegex = """package\s(.+)\s\{""".r
val packageRegex = """package\s(.+)""".r
lines
.collect {
case packageObjectRegex(name) => name
case packageNestingRegex(name) => name
case packageRegex(name) => name
}
.flatMap(_.split('.'))
.mkString("/")
}
sourceFiles.foreach { sourceFile =>
val packagePath = packageStructure(sourceFile.toScala.lines)
val destination = file"$sourceBase/$packagePath"
destination.createDirectoryIfNotExists(createParents = true)
val result = sourceFile.toScala.moveToDirectory(destination)
log.info(s"$sourceFile moved to $result")
}
}
)
}
WARNING: Make sure to backup the project before running it.

How an instance of a module created inside a class can inherit from this class (Python 3)?

'I want to build a module containing class AnimationCanvas inside (anim.py). And I want to call this module in a separate main.py file where the data (a variable) is changing (potentially with GUI). The instance animatedAxes would automatically update its plot by taking data from the variables in main.py file, while the main.py code is running (a sort of parallel processes).'
'Problem: the instance of class AnimationCanvas from the module does not see the variables of the class main in the main.py file.
I know how to do it if the class AnimationCanvas and the class main are in the same file. However I want to have an animation module (separate file), which can be used anywhere, just by importing it and writing a couple of lines.'
'I can call __init__ function of the class AnimationCanvas and pass the variables into it, but then it is a one-time effect, and if the variables change in class main, then animatedAxes instance will not see this change.'
'Single file which works (single.py):'
import matplotlib.pyplot as plt
from matplotlib.animation import TimedAnimation
from matplotlib.lines import Line2D
import numpy as np
class main():
def __init__(self):
self.size=800
main.data=np.random.rand(self.size)
# initialize animated graph routine
self.animatedAxes = AnimationCanvas()
# run random data array
for ii in range(20):
main.data=np.random.rand(self.size)
plt.pause(0.1)
class AnimationCanvas(TimedAnimation):
def __init__(self):
# initialize random data array
self.data = np.random.rand(5)
# Create animation axis and figure
self.fig = plt.figure(1, figsize=(5, 5))
self.ax = plt.axes([0.1, 0.1, 0.8, 0.8])
self.line1 = Line2D([], [], color='blue')
self.ax.add_line(self.line1)
# start animation with interval of 10 milliseconds
TimedAnimation.__init__(self, self.fig, interval=10, blit=True)
def new_frame_seq(self):
return iter(range(5*5))
def _step(self, *args):
try:
TimedAnimation._step(self, *args)
except Exception as e:
TimedAnimation._stop(self)
pass
def _draw_frame(self, framedata):
# update self.data
self.data=main.data
# update plot with self.data
self.line1.set_data(np.arange(len(self.data)),self.data)
if __name__ == '__main__':
main()
'Two files which do not work:'
'main.py:'
import matplotlib.pyplot as plt
import numpy as np
from anim import AnimationCanvas
class main():
def __init__(self):
self.size=800
self.data=np.random.rand(self.size)
# initialize animated graph routine
self.animatedAxes = AnimationCanvas()
# run random data array
for ii in range(20):
print(ii)
self.data=np.random.rand(self.size)
plt.pause(0.1)
if __name__ == '__main__':
main()
'anim.py:'
import matplotlib.pyplot as plt
from matplotlib.animation import TimedAnimation
from matplotlib.lines import Line2D
import numpy as np
class AnimationCanvas(TimedAnimation):
def __init__(self):
# initialize random data array
self.data = np.random.rand(5)
# Create animation axis and figure
self.fig = plt.figure(1, figsize=(5, 5))
self.ax = plt.axes([0.1, 0.1, 0.8, 0.8])
self.line1 = Line2D([], [], color='blue')
self.ax.add_line(self.line1)
# start animation with interval of 10 milliseconds
TimedAnimation.__init__(self, self.fig, interval=10, blit=True)
def new_frame_seq(self):
return iter(range(5*5))
def _step(self, *args):
try:
TimedAnimation._step(self, *args)
except Exception as e:
TimedAnimation._stop(self)
pass
def _draw_frame(self, framedata):
'update self.data:'
'????????????????'
'update plot with self.data'
self.line1.set_data(np.arange(len(self.data)),self.data)
'I tried to use super(AnimationCanvas,self).__init__() but it does not work.'
'In my understanding I need a direct connection between self of the class main and self of class AnimationCanvas. Any suggestions are appreciated. Thanks.'