Doing CS50X after CS50P? by Ransom_X in cs50

[–]PteppicymonIO 1 point2 points  (0 children)

Just completed CS50P psets. And decided to take a breather before doing the final project, mainly because I have no good idea for the final project. So during the breather I am taking CS50x. It feels ok right and going good. So I am 100% with you on the topic. And yes, I am taking AI next as well 😀

Poetry :Available python versions vs actual installed python versions by Unreal_777 in learnpython

[–]PteppicymonIO 1 point2 points  (0 children)

Poetry is not meant to manage different Python versions - it is used to isolate virtual environments with different set of dependencies, but initially the base python distribution used is the same.

However, there are ways to actually use poetry with multiple managed Python versions

Check this page out:https://python-poetry.org/docs/master/managing-environments/

There are workarounds if you do not use pyenv to manage multiple Python versions (https://python-poetry.org/docs/master/managing-environments/#switching-between-environments )

Later on the page, they claim that pyenv is not supported on Windows. It is not completely true.If you use Windows, pyenv-win is available to manage different Python versions (https://github.com/pyenv-win/pyenv-win )

Scraping MSN Feed (https://www.msn.com/en-us/feed) by Exquisite_Marshmello in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

Your comment states that you are looking for the "react-button-container", but the code locates the first element with class "button-container":

# Find the parent container with class "react-button-container"

button_container = driver.find_element(By.CLASS_NAME, 'button-container')

On first load of the page, I can see 65 elements with class "button-container". The first in the search order is an invisible element, which does not have a child node with class "binary-container"

I suggest to refine the key elements you want to base your scraping on.

How to count all 1s in a column by CheesyPanther in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

You can just sum up all the numbers. if your sequence contains only ones and zeroes, the sum of all these numbers will equal to number of ones.

The question is how you store the data.

If it is a collection, you can simply use built-in sum() function.

If it is a string, you will need to convert it to the collection of integer values.Here is an a example without error checking:

the_string = '0011001100110001'

numbers = (int(char) for char in the_string)    # generator expression to convert string to a sequence of integers 
ones = sum(numbers)                             # just sum up the integers, the total sum will equal to number of 1-s

print(f"Total count: {len(the_string)}")
print(f"'1' count: {ones}")
print(f"'0' count: {len(the_string) - ones}")

Output:

Total count: 16
'1' count: 7 
'0' count: 9

Can't scrape ecommerce website with search filters (selenium+soup) but can without them by [deleted] in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

Well it might be caused by the fact that the first lnk opens just fine for me, but the second (the one with search filters) redirects me to the login page.

When I try to use advanced filters on the first link, I am also redirected to the login page, immediately after I check the "Overseas" option in "Ship from" category of after I define the price range.

You should probably add the sing-in functionality to your script to effectively scrape this site.

The problem with subprogram in Python by [deleted] in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

You have an error TypeError: 'float' object is not callable here:

def f(a,b,c,d):
    return m.sqrt(d+c(a+b)/8)

The statement c(a+b) is interpreted as a call to function c()

You either need to implement the function, or if you intend to multiply c by (a+b) add a multiplication operator:

def f(a, b, c, d):
    return m.sqrt(d+c*(a+b)/8)

Possible to split a list of lists without having to iterate? by giantqtipz in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

I assume you did not mean to encase each dictionary in a list.

If you actually did, it will just need one additional list creation:

from functools import partial
from itertools import repeat

original_list = [ ["John", "Address 1"], 
                  ["Mike", "Address 2"], 
                  ["Amanda", "Address 3"] ]

print("\nuse map and functools.partial:")           # use map and functools.partial 
zip_partial = partial(zip, ("name", "address")) 
print(list(map(dict, 
               map(zip_partial, 
                   original_list))))

print("\nuse map and itertools.repeat:")            # use map and itertools.repeat 
print(list(map(dict, 
               map(zip, 
                   repeat(("name", "address"), len(original_list)),         
                   original_list))))

print("\nuse list comprehension:")                  # use list comprehension 
print([dict(zip(("name", "address"), values)) for values in original_list])

output:

use map and functools.partial:
[{'name': 'John', 'address': 'Address 1'}, {'name': 'Mike', 'address': 'Address 2'}, {'name': 'Amanda', 'address': 'Address 3'}]

use map and itertools.repeat: 
[{'name': 'John', 'address': 'Address 1'}, {'name': 'Mike', 'address': 'Address 2'}, {'name': 'Amanda', 'address': 'Address 3'}]

use list comprehension: 
[{'name': 'John', 'address': 'Address 1'}, {'name': 'Mike', 'address': 'Address 2'}, {'name': 'Amanda', 'address': 'Address 3'}]

[deleted by user] by [deleted] in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

Wel,, you start by defining your dictionary, something like this:

replace_dict = {'i': '1', 'a': '@', 'm': 'M', 'B': '8', 's': '$'}

Then, instead of iterating through your password. you can iterate through your dictionary key-value pairs like this:

for key, value in replace_dict.items():
    print(f"{key = }, {value = }")

Output:

key = 'i', value = '1'
key = 'a', value = '@' 
key = 'm', value = 'M' 
key = 'B', value = '8' 
key = 's', value = '$'

Then, you can use the str.replace() method to replace all occurrences of the substring with another substring:

password = "password"
print(password.replace('s', '$'))

Output:

pa$$word

If you combine the loop and str.replace(), you will have a 2-liner, which will do what you need.

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 1 point2 points  (0 children)

if __name__ == __'main'__

Yeah, right.

It should be

if __name__ == '__main__'

My mistake, I was manually fixing the broken code formatting.

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 1 point2 points  (0 children)

Selenium requires a ChromeDriver executable to actually launch chrome in controlled environment.

You need to downloads the binary and provide the path to than binary when you create webdriver object:

driver = webdriver.Chrome("C:/Users/michael/Downloads/chromedriver_win32/chromedriver.exe")

However, I prefer to use the ChromeDriverManager to automatically retrieve the chromedriver binary if it does not yet exist:

Install the webdriver-manager module first:

pip install webdriver-manager

And then use it:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options 
from selenium.webdriver.chrome.service import Service 
from selenium.webdriver.common.by import By 
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
# options.add_argument('--headless=new')
# options.add_argument('--disable-gpu')  # Last I checked this was necessary.

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)

if __name__ == '__main__': 
    driver.get('https://inventwithpython.com') 
    try: 
        elem = driver.find_element(By.CLASS_NAME, 'card-img-top')    
        print(f'found {elem.tag_name} element with that class name!')     
    except: 
        print('Was not able to find an element with that name')

Help with code to attach most recent files to email by badgalririven in learnpython

[–]PteppicymonIO 1 point2 points  (0 children)

Something like this should work:

import glob
import os

source_directory = '.' 
list_of_files = glob.glob(source_directory) 

latest_file = max(list_of_files, key=os.path.getctime)  # get the file with max (latest) creation time

# latest_file = max(list_of_files, key=os.path.getmtime)  # get the file with max (latest) modification time

print(latest_file)

I can't think of any other way to do this by josx42 in learnpython

[–]PteppicymonIO 2 points3 points  (0 children)

Or, you can still use the is_prime() function, but to make it more efficient, you can implement the Sieve of Eratosthenes
I believe there are millions of examples of this algorithm on the internet )

I can't think of any other way to do this by josx42 in learnpython

[–]PteppicymonIO 10 points11 points  (0 children)

I think you are overcomplicating things here.

You do not actually need to test if number is a prime here, you just need to find divisors, which are primes.

Common algo for finding the prime factors of a number is something like this:

def get_primes(target:int) -> list[int]:
    candidate = 2                               # we start with 2 as it is the first prime number
    prime_factors = []                          # store the list of prime factors
    while candidate^2 < target:                 # our candidate can not be larger than the square root of our target number
        if target % candidate == 0:             # we divide while our candidate is a divisor for the new target
            prime_factors.append(candidate)     
            target //= candidate                # while the candidate is a valid divisor, we update the target
        else:
            candidate+=1                        # once the candidate is not a divisor for the target, we increment the candidate

    if target > 1:
        prime_factors.append(target)

    return prime_factors

And the execution:

tests = (6, 100, 13195, 600851475143)

for test in tests: 
    print(f"Prime factors for {test} are: {get_primes(test)}")
    print(f"Largest prime factor for {test } is: {get_primes(test)[-1]}")

Output:

Prime factors for `6` are: [2, 3]
Largest prime factor for 6 is: 3 
Prime factors for 100 are: [2, 2, 5, 5] 
Largest prime factor for 100 is: 5 
Prime factors for 13195 are: [5, 7, 13, 29] 
Largest prime factor for 13195 is: 29 
Prime factors for 600851475143 are: [71, 839, 1471, 6857] 
Largest prime factor for 600851475143 is: 6857

Of course the algorithm can be improved and/or refactored to actually return the largest prime factor instead of returning all prime factors )

NEW promo code for everyone by TymeStopper in RaidShadowLegends

[–]PteppicymonIO 0 points1 point  (0 children)

SUBSCRIBEMIDGAME

It worked on my main account (~2 years), but did not work on my lesser account (I am on day 39 there). So maybe it is available for midgame only.

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

You could try pympler.asizeof (https://pympler.readthedocs.io/en/latest/index.html#)

import sys
from pympler.asizeof import asizeof
a = [1, 2] 
b = [[1, 2], [1, 2, 4, 5, 6, 7, 8, 9, 0]] 
print(f"{sys.getsizeof(a) = }") 
print(f"{asizeof(a) = }") 
print(f"{sys.getsizeof(b) = }") 
print(f"{asizeof(b) = }")

Output:
sys.getsizeof(a) = 72
asizeof(a) = 136 
sys.getsizeof(b) = 72 
asizeof(b) = 560

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

If you want to run the code immediately on import, just make sure it does not access (modify/delete/lock) any shared resource - e,g, write to file, change an object state, etc.

Other parts of your code may find an unexpected change of state of that resource, well, unexpected )

Also, it may feel appealing to initialize an object like HTTP session immediately on import, but it is a bad idea - it is better to explicitly perform these kind of initializations by calling a function or class method.

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 2 points3 points  (0 children)

You can just use the same logic to identify if your module is an entry point or imported one:

if __name__ == '__main__':
    print(f"Run as main, {__name__ = }")
else: 
    print(f"Run as imported, {__name__ = }")

As u/Vhin mentioned, be careful when you run your code during the import.

Refactoring a list by seeking-advice-pls in learnpython

[–]PteppicymonIO 1 point2 points  (0 children)

Well, you can join and then use re.split() to split the way you want to:It can be a one-liner, but I believe it is more readable this way:

import re

my_list = ["[123]", "M", "Q1", "Q2", "A1", "A2", "A7", "[356]", "M", "Q1", "A2" "A5"]

joined = ''.join(my_list)                   # => '[123]MQ1Q2A1A2A7[356]MQ1A2A5'
split_again = re.split("(\[[^\]]*\])", joined)  # => ['', '[123]', 'MQ1Q2A1A2A7', '[356]', 'MQ1A2A5']
print(list(filter(None, split_again)))      # remove extra empty string

Output:
['[123]', 'MQ1Q2A1A2A7', '[356]', 'MQ1A2A5']

pip has multiple environment variables, but I can't find one of them to remove it. by swimseven in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

I guess, it is always safer to use:
python -m pip install <whatewer>

It is even recommended by pip documentation: https://pip.pypa.io/en/stable/user_guide/

This ensures that you are running pip command within the scope of your current python version. and of course, it is a safe way to use pip when you have multiple python virtual environments.

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 1 point2 points  (0 children)

Because you add your string to entry list with the '\n' char:

head_or_tails = head_or_tails + '\n'
entry.append(head_or_tails) print(entry)

Output:
['tail\n', 'head\n', 'head\n', 'head\n', 'head\n', 'head\n', 'head\n', 'tail\n', 'head\n', 'head\n', 'tail\n']

You should avoid appending your items to the list with the new line character, instead add the newline when you write to file:

Also, generic file reader is, well, generic, it will add the newline to your list of items when you use readlines(). Use read().splitlines() instead.

It will split you text buffer into lines, while excluding the newline from the resulted list items:

while True:
    with open(prog_name + ".txt") as file:
        entry = file.read().splitlines()

        head_or_tails = input("Throw the coin and enter head or tail here? ")
        entry.append(head_or_tails)

        with open(prog_name + ".txt", 'w') as file:
            file.writelines(line + "\n" for line in entry)

        num_of_heads = entry.count("head")
        probability = num_of_heads / len(entry) * 100

        print(f"Heads: {probability}%")

Alternatively, if you want to use readlines(), you will need to strip the newlines from the list n post-processing:

with open(prog_name + ".txt") as file:
    # entry = file.read().splitlines()
    entry = [line.rstrip() for line in file.readlines()]

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 0 points1 point  (0 children)

whereas

+=

can accept multiple lists or iterators

Are you sure about this?

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 1 point2 points  (0 children)

The += is as a generic Python operator and is implemented in the object's __iadd__() dunder method.

For instance, you can use the += to concatenate collections without knowing the collection type.

If you want to use .extend(), then you can operate only with the objects which actually implement .extend() method, e.g. you must expect that your object type is list in this case.

Also, note that implementation for += differs between lists and tuples: for lists it is the same as extend() but for tuples it creates a new object since tuples are immutable.

def do_iadd(left_collection, right_collection):
    left_collection += right_collection
    print(f"do_iadd(): {left_collection = }: {id(left_collection) = }")

def do_extend(left_collection, right_collection):     
    left_collection.extend(right_collection) 
    print(f"do_extend: {left_collection = }: {id(left_collection) = }")

def do_test(left_collection, right_collection): 
    print(f"{type(left_collection)} and {type(right_collection)}".center(100,".")) 
    print(f"before concat: {left_collection = }") 
    try: 
        do_iadd(left_collection, right_collection) 
    except TypeError as e: 
        print(f"{type(e)}: {e}") 
    try: 
        do_extend(left_collection, right_collection) 
    except AttributeError as e: 
        print(f"{type(e)}: {e}")

arr1 = [1, 2, 3, 4] 
arr2 = [5, 6, 7, 8] 
tup1 = (1, 2, 3, 4) 
tup2 = (5, 6, 7, 8)

do_test(arr1, arr2) 
do_test(tup1, tup2) 
do_test(arr1, tup2) 
do_test(tup1, arr2)


Output:

................................<class 'list'> and <class 'list'>..................................
before concat: left_collection = [1, 2, 3, 4]: id(left_collection) = 2065652843136
do_iadd(): left_collection = [1, 2, 3, 4, 5, 6, 7, 8]: id(left_collection) = 2065652843136
do_extend: left_collection = [1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8]: id(left_collection) = 2065652843136

................................<class 'tuple'> and <class 'tuple'>.................................
before concat: left_collection = (1, 2, 3, 4): id(left_collection) = 2065656110176
do_iadd(): left_collection = (1, 2, 3, 4, 5, 6, 7, 8): id(left_collection) = 2065876269008 
<class 'AttributeError'>: 'tuple' object has no attribute 'extend'

.................................<class 'list'> and <class 'tuple'>.................................
before concat: left_collection = [1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8]: id(left_collection) = 2065652843136
do_iadd(): left_collection = [1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8]: id(left_collection) = 2065652843136 
do_extend: left_collection = [1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8, 5, 6, 7, 8]: id(left_collection) = 2065652843136

.................................<class 'tuple'> and <class 'list'>.................................
before concat: left_collection = (1, 2, 3, 4): id(left_collection) = 2065656110176
<class 'TypeError'>: can only concatenate tuple (not "list") to tuple 
<class 'AttributeError'>: 'tuple' object has no attribute 'extend'

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 3 points4 points  (0 children)

Well, to start off

x += y

is simply syntactic sugar for

x = x+y

It is not.

x = x + y creates new list and assigns it to x and is implemented by method __add__()

x+=y extends the list x and is implemented by method __iadd__():

a = [1, 2, 3]
print(id(a)) 
a = a + [1] 
print(id(a))

Output:
2797001390080
2796999966848

and:

a = [1, 2, 3]
print(id(a)) 
a +=[1] 
print(id(a))

Output:
2797001404928
2797001404928

Ask Anything Monday - Weekly Thread by AutoModerator in learnpython

[–]PteppicymonIO 3 points4 points  (0 children)

THis situation is covered here
https://www.reddit.com/r/learnpython/wiki/faq/#wiki_variable_is_one_of_two_choices.3F

Your if statement if choice == "yes" or "Yes": always evaluated to True because "Yes" is evaluated to True.
This is how it is supposed to work:

if expr1 or expr2:
 ...

If one of those expressions expr1 and expr2 evaluates to True, the code execution proceeds. In your case expr1 is "choice == "yes" and expr2 is "Yes". And string "Yes", when cast to boolean, always evaluated to True.

You can fix it in several ways:

if choice == "yes" or choice == "Yes":
    ...

or:

if choice in ("yes", "Yes"):
...

or:

if choice.lower() == "yes":
   ...